For agents
Scout is built to be driven by your own AI agent (Claude Code, Codex and similar): you ask “what are the new jobs?”, the agent asks Scout, shows you a grid, asks you the open questions and saves what you say. The browser UI is there when you want it: for reading a job, for the resume picked for it and for the PDF.
Anything GigAI gives your agent is sent to that agent’s model provider. Agents get no contact data from GigAI, but an agent with shell access can read local files.
Read The security model before you let an agent use Scout. The general CLI discovery commands are on For agents.
New here? Use it from your agent says what to install and what to type for Claude Code, Codex and other agents. To have the agent do the whole setup, give it Start here. To throw away stored data and start again from a resume file, see Start fresh.
The daily workflow
Section titled “The daily workflow”Every command below is local. A step that spends a model call says so, and none is made until you say yes.
1. What is new
Section titled “1. What is new”gigai scout new --jsonThis reads the stored postings (the background checks keep them fresh; no job board is asked) and lists what is new since your last check, across all your active profiles. The first time it looks back 7 days. At most 50 new postings are listed; the count covers all of them.
The order of the grid. Postings with a current assessment come first, then postings whose
only assessment is old, then postings not assessed yet. Inside each group: Scout’s
recommended label first, then the verdict (matched, needs your answers, other, not a match),
then the rank score, then the newest. gigai scout jobs list and the Jobs page use the same
order.
It asks before it assesses. When new postings are not assessed yet, the reply carries a question with the count and an estimate from your own past calls, for example “12 new postings. Assess them? ~12 calls”. The postings are shown ranked, not assessed. Nothing is assessed until you answer:
gigai scout new --yes --since 2026-10-03T14:02:00Z --json # yes: the command the reply gives in question.yes.cli; one model call per posting, then the gridgigai scout new --no-assess --json # no: show the grid with ranks onlyThe agent’s job is to tell you the count and the estimate, and wait for your word. On a yes it
runs the command the reply gives in question.yes.cli. That command carries --since, the
start of what you were shown, so the yes covers exactly those postings, also when another check
ran in between. A bare gigai scout new --yes --json right after the question assesses the same
postings.
Old assessments are a second question. A posting whose only assessment was made with an
older prompt, other settings or an old run is not “new”, so --yes never touches it. The reply
asks about those separately, with their own count and estimate, for example “497 have only an
old assessment; re-assess? ~497 calls”. The yes to that question is its own flag:
gigai scout new --reassess-stale --json # yes to the old ones only (one model call each)gigai scout new --yes --reassess-stale --json # yes to both questionsIn the JSON, counts.to_assess is the new postings that no matching profile has assessed, and
counts.only_stale is the postings that have only an old assessment. After a full --yes,
to_assess is the ones that failed, if any.
Progress while it assesses. A batch prints lines like assessed 120 of 333 · ~18 min left
to the error stream (stderr), so with --json the standard output is still the reply alone. A
batch of 20 or fewer prints every result; a larger one at most one line every 10 seconds, and
always the last. The reply’s ranking block says how far the background ranking is, per
profile (ranked of total).
With nothing new, the reply reads “Nothing new since your last check” and lists the 10 postings that still need your attention.
The grid has four columns: the posting (company, role, work mode, salary if stated, and the
profiles it matches), its score, whether the resume needs more (the “Needs tailoring” column: the requirements not yet met),
and its open questions. The score column is words, never a bare percent: the verdict, how many
requirements are met, and the rank, for example Matched · 9 of 11 requirements · rank 96,
Matched (old assessment: older prompt) · 3 of 3 requirements · rank 95 or
rank 97 · not assessed.
A plain gigai scout new moves the “new since” mark to now. --peek and --profile ID look
without moving it.
Assess one posting, or the ones you pick
Section titled “Assess one posting, or the ones you pick”gigai scout new assesses what is new. For one posting, or the ones a filter selects, use
gigai scout jobs assess. It asks first too:
gigai scout jobs assess URL --json # no model call: the question, the estimate, what would be sentgigai scout jobs assess URL --yes --actor agent --json # after your yes: one model call per postinggigai scout jobs assess URL --again --yes --actor agent --json # again, although its assessment is currentWhat one assessment sends. One assessment sends to your model target: the stored posting; your resume (the lines of your master resume picked for the posting, or the profile’s own resume) with its contact lines removed by pattern; your search preferences (sponsorship, countries, location, titles, work mode); your saved answers; and the saved stories that match the posting. Pattern removal can miss an unusual name or contact format, so it is not a guarantee. A profile id is not contact data. With codex_cli or claude_cli the model target is your own login.
Cancel and stop. gigai scout jobs assess --cancel stops the batch that is running, also
one the Jobs page started: no further model call starts, the calls in flight finish, and what
is assessed is kept. The same assess command again takes the rest. gigai scout stop stops
the server and ends the model calls it started.
The preview says it exactly. Without --yes the reply is status: "ask": no model call was
made, and model_input_summary says what the postings asked about would send and where. For
each profile: its id and label, and resume_source (master_evidence: the lines of your master
resume picked for the posting; profile_view: that profile’s own resume). Then answers_used
and stories_used, the model_target and where it runs (model_target_runs: local,
own_login or api_key), and public_fetch_needed (a posting with no stored text is fetched
from its public board first). It holds ids, labels and counts, never a line of your resume or
answers. The agent shows you that summary and the estimate, and waits for your word. Over the
API the same reply comes from POST /api/postings/assess without approve.
Three approvals, kept apart. Three approvals are separate: the user’s choice to assess; Scout’s own –yes (approve: true over the API); and the agent runtime’s own sandbox or model-provider approval. –yes does not bypass the runtime’s policy, and an API or UI route is not a workaround: an agent whose runtime refuses the command quotes the refusal and asks the user for the exact missing authorisation.
The third one is the one Scout cannot see. Claude Code, Codex and other agent runtimes have
their own rules for what a command may send and where, and they can refuse
gigai scout jobs assess ... --yes before gigai even starts. Scout returns no error then,
because it never ran. The agent should not stop silently and should not try another route. It
tells you what its runtime said, word for word, and asks for exactly what is missing, for
example: “My runtime did not let me run gigai scout jobs assess URL --again --yes: it sends
the stored posting and your resume’s evidence view to codex_cli, your own Codex login. Do you
authorise that?” Your yes there is the runtime’s approval; --yes is Scout’s.
When an assessment fails. A failure Scout controls has a typed cause. In the JSON, beside
the code (error.code for gigai scout assess, error_code on an item of assessed.failed
for a batch, error.code over the API), four fields say what happened: model_call_started,
may_have_used_tokens, fresh_assessment_stored (always false: the assessment shown, if
any, is the earlier one) and next_action.
| Cause | Model call started | May have used tokens | Next action |
|---|---|---|---|
model_target_unavailable |
no | no | Fix the model target, then assess again: gigai models shows what is configured and gigai setup changes it (a codex_cli or claude_cli target needs that command on PATH and logged in). |
model_denied |
no | no | GigAI’s own settings refused this call before anything was sent. Ask the user to allow the model target in gigai setup or to pick another one; do not retry unchanged. |
model_unavailable |
yes | yes | The model target did not answer. Check that it is running and logged in (gigai models), then assess again; that is one more model call. |
assess_timeout |
yes | yes | The model call ran out of time. Check assessed_at for this job first; if it is unchanged, assess again (one more model call) or pick a faster model target. |
model_output_invalid |
yes | yes | The model answered twice with something that is not an assessment. Assess again (one more model call) or pick another model target. |
assessment_not_stored |
yes | yes | The model answered but the result could not be written. Check free disk space and that the GigAI home is writable, then assess again; that is one more model call. |
assess_timeout is the timeout. Any other code (a bad URL, a missing profile) has no model
call behind it, and its message says what is wrong.
After an interruption, look before you retry. A timeout, a killed command or a lost connection does not say whether the assessment finished. Read the posting’s row:
gigai scout jobs list --query "WORDS" --json # the row: assessment.assessed_at and stale_reasongigai scout jobs search "TITLES" --json # free search of every stored posting: no model call, nothing storedA newer assessment.assessed_at with stale_reason null means it finished: report the
verdict, and do not assess again (that would be a second model call). An unchanged
assessed_at, or a stale_reason that is still there, means it did not: say so, never “done”,
and assess again only on your yes.
The browser, and a sandbox. gigai scout run starts Scout and opens the browser; it prints
the address, http://127.0.0.1:8765 unless you gave another port. One job’s page is that
address plus #/jobs/ and the posting’s URL percent-encoded, for example
http://127.0.0.1:8765/#/jobs/https%3A%2F%2Fjobs.lever.co%2Fnorthwind%2F1a2b3c: give the user
that link when they want to look at a job. --no-browser is a choice (an agent session with no
display), not a requirement. Inside a restricted agent sandbox a check of localhost can fail
while Scout is running, and the process list can be hidden. gigai scout status keeps the two
apart: it says process: running (pid N); API: not reachable from here (state unreachable),
never just “stopped” or “running”. Do not restart Scout on that alone, and do not read a “port
in use” from a sandboxed gigai scout run as a second server: check from outside the sandbox,
or ask the user to reload the page.
2. Public and private are separate calls
Section titled “2. Public and private are separate calls”gigai scout new never mixes text written by strangers with text about you. The default reply
holds only posting data (public, untrusted) and your open questions. “What matches”, which is
built from your own resume, answers and stories, is a second call:
gigai scout new --yours --jsonIts reply holds your evidence only and names each posting by its link, never by its text. An
agent should not paste the two side by side: a posting can contain text meant to steer an agent,
and keeping your own text out of that context is the point of the split. Over the API the same
two calls are GET /api/new and GET /api/new/yours, and every reply says what it holds in the
X-GigAI-Labels header (public-untrusted, user-private, both for a route that mixes them,
or none).
3. Answers, and “make this a story?”
Section titled “3. Answers, and “make this a story?””The agent asks you the open questions. What you say is kept once and reused by every later assessment, for every profile.
-
A short fact is saved as an answer:
Terminal window gigai scout answers save cloud:gcp --question "Do you have GCP experience?" --answer-text "Yes, 4 years, GKE and BigQuery" --as agent --json--as agentrecords that the agent wrote it (the Answers and stories page says “Written by your agent”); without it the command line records the write as yours. If you point the agent at your own code or notes and it answers a question from them, it adds where the answer came from:--source "from the user's repo infra-charts, at the user's request". -
A reply with substance (a project, a problem, an outcome) gets the question “Want me to make this a story?”. On a yes the agent drafts a short narrative from your own words, shows it to you, and saves it when you agree:
Terminal window gigai scout story save --title "Cut CI time 60% at Acme" --raw-text "Our builds took forty minutes, so I moved the runners to Kubernetes and cached the layers." --situation "Builds took forty minutes and blocked every merge." --action "Moved the runners to Kubernetes and cached the image layers." --result "Build time fell 60 percent." --tag ci --answers "Tell me about a time you improved a slow process" --as agent --json
Every write is checked on your computer: text that looks like an email address, a phone number, a
link or a street address is refused (personal_info_refused). The check works on shapes. It does
not recognise a name, so don’t put yours in an answer or a story.
Answers and stories below has the full reference.
4. Process waiting work
Section titled “4. Process waiting work”The background pipeline is OFF by default in 0.1.11. Saving an answer starts nothing in the
background, gigai scout new has no waiting work to process, and no resume is tailored: the
resume for a job is picked from your master at assessment, word for word (step 5). Skip to “An
answer makes the job’s first assessment old” below. The rest of this step describes the pipeline
as it works in a home whose settings explicitly enable it (pipeline.enabled true, or
GIGAI_SCOUT_PIPELINE=on; a home that enabled it on 0.1.10 keeps it): saving an answer puts the
jobs that asked that question into it: tailor a resume for the job, assess the tailored resume,
compute the Scout ATS score, set the Scout label. It works only on jobs you engaged with (you
answered one of their questions, or you said “process now”). Its limits:
- 10 jobs per trigger. One answer can concern many jobs. The first 10 run; the rest wait for your approval.
- 40 model calls a day for the pipeline. The call that would go over the limit is not made; the job waits until the next day.
- First assessments are never automatic. A posting is assessed for the first time only when you say yes (step 1, or Assess these on the Jobs page).
While Scout runs with the pipeline enabled, it works by itself. gigai scout new tells you when work waits
(“3 waiting (2 need your approval), process now? ~6 calls”). On your yes:
gigai scout new --process --json # approve what waits, run it nowgigai scout pipeline status --json # what is queued, running, done; today's countsgigai scout pipeline approvals list --json # what waits for a yes, with the estimategigai scout pipeline process <job-url> --json # one job, nowgigai scout pipeline approvals approve <approval-id> and approvals deny <approval-id> decide
one approval. An agent approves only on your word.
An answer makes the job’s first assessment old. That assessment was made before your
answer. Until the job is assessed again its row reads “old assessment: answers changed”, and its
Scout label is needs_attention with the reason base_assessment_stale, whatever the tailored
resume scored. To have the label made from a current assessment, save the answer with a
re-assess of the job that asked (one model call; the pipeline runs after it):
gigai scout answer cloud:gcp --question "Do you have GCP experience?" --answer-text "Yes, 4 years, GKE and BigQuery" --reassess <job-url> --as agent --jsonOn the job’s page that is the question box and Re-assess. For a job the pipeline already labelled, assess it again and run its pipeline again:
gigai scout jobs assess <job-url> --again --yes --actor agent --json # one model callgigai scout pipeline process <job-url> --json # makes the label againOther jobs that asked the same question keep their old assessment until they are assessed again
(gigai scout new asks about them: “N have only an old assessment; re-assess?”).
A resume you edited is never replaced by the background. If you changed a line of a job’s
resume, the pipeline (where enabled) keeps it and works with your text. To get a new pick for that
job, take the proposed one yourself (gigai scout resume pick --job-url <job-url> --use-proposed).
5. The picked resume and the PDF
Section titled “5. The picked resume and the PDF”gigai scout resume tailor is switched off in 0.1.11: it answers tailoring_off (exit 1, no model
call). The assessment picks the resume for the job from your master, word for word; GigAI checks
that every line it shows is a line you wrote.
gigai scout resume pick --job-url <job-url> --json # the picked resume as stored. No model callgigai scout resume pdf --job-url <job-url> --json # Apply: the PDF. Local, no model callThe PDF an agent makes has no name and no contact details, because GigAI has none to give it. The command prints a line like
Open in Scout to add your name and contact details and download: http://127.0.0.1:8765/#/pdf/<profile>/<job>(finish_url in the JSON). The agent gives you that link. You open it, type your details in the
Generate PDF form in your own browser, and download the finished PDF. The details go into that
one PDF and are not kept. An agent can’t do this step for you unless it controls your browser,
and it should not ask you for those details.
Every line comes from your resume, answers or stories. Read it before you send it.
Where the files are. Each job has its own folder in your jobs folder,
~/Documents/GigAI/jobs/<company>/<role>/, and its resume (markdown) is resume.md there: no
date in a name, two roles at one company are two folders. gigai scout status shows the folder;
gigai scout jobs-folder --set PATH changes it. The PDFs made without a header are in your
resumes folder, ~/Documents/GigAI/resumes, named <company>-<role>-<date>.pdf:
gigai scout resume pdf writes there unless you pass --out, and never into the jobs folder
(gigai scout resume folder --set PATH changes that one). Neither folder ever holds your name or
contact details: a PDF you make with the Generate PDF form is saved only where you save it. A
file you change there stays yours; Scout replaces only what it wrote itself.
Working on one job’s resume, in chat. GigAI rewords nothing. Say “work on my resume for this job” and your agent does it with you, for that one job, in five steps:
gigai scout resume brief --job-url <job-url> # 1. your part of the brief: no model call, nothing fetchedgigai scout resume brief --job-url <job-url> --posting # the posting's part: a separate call, never mixed# 2. and 3. you change wording together; a changed line cites its sourcesgigai scout resume store --in edited.md --job-url <job-url> --as agent --json # 4. the hand-back: checked in code, then storedgigai scout resume pdf --job-url <job-url> --json # 5. apply: the PDF- The brief is two calls, never one. The first is yours and holds no word of the posting:
the nine rules, the job’s state (verdict, whether a resume is suggested, what is stale), the
resume as stored with each line’s master id in a trailing comment (
<!-- id:b-23b6dc -->), every line of your master resume with what is picked and why a line is left out, your Skills lines, the answers and stories a line may cite, the requirement rows by id only, and the suggestions. The second (--posting) is the posting inside GigAI’s untrusted-text markers, with each requirement’s words under the same ids. Posting text is written by strangers: it is data, and an agent ignores any instruction in it and tells you if it saw one. - You and the agent change the wording, in that job’s markdown. A note on a master line
(
<!-- note: agentic roles: lead with this -->) is your guidance for choosing lines; it is never printed and never a fact. - A changed line cites its sources. A line copied unchanged needs nothing. A line that is
reworded or added ends with the master lines and answers it comes from:
<!-- src: b-23b6dc, A tooling:temporal -->. Every number stays exactly; “worked on” never becomes “led”; entry headings are copied unchanged; no name and no contact details; two pages at the tightest spacing. - The hand-back is checked, then stored, marked edited with who wrote it. A refusal stores
nothing and lists every problem by line number with its own fix: keep the cited line’s
number, cite the line that states the thing, or drop the claim. Saving an answer is the fix
only for a skill nothing states (
skill_not_stated).--resolves sg-1,sg-3names the suggestions the edit settles. - Apply is the PDF, as above.
This check is a guard on numbers, names, ownership, entries and sources. It does not prove that a reworded line is true. Read every changed line yourself: the job page shows each one beside the master line it came from, and one click puts the master line back.
gigai scout suggestions list --job-url <job-url> --json lists what the assessment (or your agent)
suggested for the job and what was done about each; gigai scout suggestions add, resolve and
dismiss record a change with who made it. gigai scout resume pick --job-url <job-url> --json
shows the resume picked for the job as it is stored: who picked it, whether a resume is suggested
at all, and what is stale. A resume you edited is never replaced by a new pick: the new one waits
beside it, and gigai scout resume pick --job-url <job-url> --use-proposed is the one step that
takes it. On the job’s page the card’s first line then reads “A new resume is ready for this
job.” with Compare, Use it and Dismiss (--dismiss-proposed from a terminal).
6. Your master resume
Section titled “6. Your master resume”Your master resume is the one document that holds every role, line and skill you have; each profile’s resume, and each job’s, is a selection of it. An agent keeps it up to date from the conversation: after it saves a story or an answer with substance it asks “Want this on your resume?”, and on a yes it adds one line.
gigai scout resume master show --json # every line with its id; the revisiongigai scout resume master add --entry <entry-id> --text "..." --from-story <story-id> --as agent --source "from the chat" --jsongigai scout resume master add --skill Helm --from-answer <question-id> --as agent --jsongigai scout resume master add --entry <entry-id> --text "..." --lab --when "Oct 2026" --as agent --json # personal lab, never productiongigai scout resume master edit <line-id> --text "..." --revision <n> --as agent --jsongigai scout resume master remove <line-id> --revision <n> --as agent --json- The line is your facts. The agent writes the line from what you said;
--from-storyand--from-answerlink it to that story or answer, and--sourcesays where the evidence came from.gigai scout resume master showshows who wrote each line and its source. A number in the line that the story or answer does not state comes back as a warning to check with you. - Nothing is overwritten blindly. An edit or a removal names the revision it read; if the
master changed since, it is refused with
revision_conflictand the current revision. - No contact data. Text that looks like an email, a phone number, a link or an address is refused, and nothing of it is stored.
- No second copy of a line. A line the master already has in other words is not added: the
reply lists the line it looks like (
status: near_duplicate). The agent changes that line, or adds both with--forcewhen you say so. - Removed means retired. No resume shows a removed line any more, but it is not lost:
gigai scout resume master show --retiredlists it with its text, andgigai scout resume master add --restore <line-id>puts it back under the same id.
A profile whose resume shows a line you changed or removed follows by itself. A new line is only
offered to a profile (gigai scout resume master selection status), never added to it.
Use it from your agent
Section titled “Use it from your agent”Three ways to teach an agent the daily loop. They carry the same instructions; pick the one your agent reads.
| Your agent | Use | How it is picked up |
|---|---|---|
| Claude Code | The skill file: gigai agent-skill --format skill |
Claude Code loads it by itself when you ask about Scout or job postings, or when you type /gigai-scout |
| Codex | An AGENTS.md section: gigai agent-skill --format agents-md |
Codex reads AGENTS.md at the start of every run |
| Any other agent | The same AGENTS.md section, or paste what gigai agent-context prints |
Whatever instruction file your agent reads; or the chat itself |
gigai agent-context prints a one-line summary of the CLI, and with --json the full manual of
every command. It teaches the commands, not the loop: use it when your agent has no instruction
file at all.
The same instructions carry a second section, for a cover letter: your agent tailors a letter of your own to one job, from your master resume, and saves it with a claims trace beside it. See Cover letters.
Claude Code
Section titled “Claude Code”-
Install the skill. The command creates the folders it needs:
Terminal window gigai agent-skill --format skill --out ~/.claude/skills/gigai-scout/SKILL.mdThat folder is for all your projects. For one project only, write it to
.claude/skills/gigai-scout/SKILL.mdinside that project instead.--outrefuses to replace a file that exists unless you add--force. -
Print the permissions snippet and merge it into your settings yourself:
Terminal window gigai agent-permissionsPut it in
~/.claude/settings.json(all projects) or.claude/settings.local.json(this project only), merged into thepermissionsyou already have. It allows thegigaicommand and Scout’s local API athttp://127.0.0.1:8765/, and denies reading~/.gigaidirectly. If you started Scout with--port, print it withgigai agent-permissions --port <port>, and use your port wherever a command on this page says8765. GigAI prints it and never applies it. It does not read or write your agent’s settings. -
Start a new Claude Code session, so that the skill is listed.
-
Type:
What’s new on Scout?
What a first session should look like (an illustration with a made-up user and made-up postings, not a recording):
You: What’s new on Scout?
Claude Code: (loads the gigai-scout skill, runs
gigai scout new --json) 14 new postings across your 2 profiles. They are ranked, not assessed. Assessing them is about 14 model calls on your Codex login. Go ahead?You: Yes.
Claude Code: (runs
gigai scout new --yes --since 2026-10-03T14:02:00Z --json) Assessed 14 of 14. The top one: Northwind, Staff Backend Engineer, remote: needs your answers, 9 of 11 requirements, rank 96. It asks: have you run Kafka in production?
The snippet is a guard against accidents, not a security boundary: see
The security model. The curl rules cover only a command written exactly
as curl http://127.0.0.1:8765/...; the agent should prefer the gigai command. Without the
snippet everything still works: Claude Code asks you before each command.
If your project already has a CLAUDE.md, Claude Code does not read an AGENTS.md there; the
skill file is the simpler route.
-
Print the instructions as an
AGENTS.mdsection:Terminal window gigai agent-skill --format agents-md -
Add the section to the end of the file Codex reads, after a blank line:
~/.codex/AGENTS.mdfor every project, or theAGENTS.mdat the root of one repository. (If you keep anAGENTS.override.mdthere, Codex reads that one instead.) -
Start Codex and type “What’s new on Scout?”.
What to expect from Codex’s own safety settings. By default Codex runs commands in a sandbox
that can write only inside the folder you started it in (workspace-write), with network access
off, and asks you when a command needs more (on-request). GigAI keeps its data in ~/.gigai,
outside that folder, and installing or Update sources needs the network. So expect Codex to
ask for approval for those commands. We have not tested every case; approve what you recognise.
Do not turn the sandbox off for GigAI (danger-full-access, or bypassing approvals). Nothing
here needs it.
To give Codex a docs page such as Start here: by default Codex’s web search reads a
cached index, not the live page, so it may not find a new page. Either start it with live web
search (codex --search "<your prompt>"), or put “run curl -fsSL <the page address> and read
it” in the prompt. The starter prompt in the
README does the second.
Any other agent
Section titled “Any other agent”- Paste the
AGENTS.mdsection (gigai agent-skill --format agents-md) into the instruction file your agent reads. - While Scout runs, the local API describes itself:
GET http://127.0.0.1:8765/llms.txtis a short plain-text guide, andGET http://127.0.0.1:8765/api/openapi.jsonis the full OpenAPI spec. See Discover the API. - The docs site has a plain-text entry point too:
llms.txtbeside these pages, with the setup steps and links.
What it costs
Section titled “What it costs”gigai scout new asks before it assesses, with the count and an estimate from your own past
calls. gigai scout metrics shows the averages after the first calls. Background work has
daily caps: 40 pipeline model calls (only where the pipeline is enabled; it is off by default) and 100 rank calls. The first run is the expensive one; a
normal day is a few dozen new postings. Token usage has measured numbers for
Codex and Claude Code.
The security model
Section titled “The security model”Anything GigAI gives your agent is sent to that agent’s model provider. Agents get no contact data from GigAI, but an agent with shell access can read local files.
What that means, plainly:
- Your agent’s provider sees what your agent reads. When Claude Code or Codex reads a job grid, your answers or a resume from Scout, that text goes to Anthropic or OpenAI as part of the conversation. GigAI can’t stop that. The only way to keep everything on your computer is to run both Scout and your agent on a local model.
- GigAI has no contact data to give. It never stores your name, email, phone, address or links, so no command and no API route can return them. See Privacy and security for the limits of that promise.
- An agent that can run commands can read GigAI’s files. It runs as you, so file permissions
do not separate it from your answers, stories and resume under
~/.gigai. The permissions snippet lowers the chance of an accident. It can’t stop an agent that decides to read the files another way. - Job postings are written by strangers and can contain text meant to trick your agent.
Scout marks posting text as untrusted, keeps it apart from your own text in
gigai scout new, and fences it in its own prompts with a rule that it is data, never instructions. That lowers the risk. It does not remove it. Keep your agent’s permission prompts on. - Scout checks what it sends out, as a backstop. Every JSON reply from the local API is
scanned, and text shaped like an email address, a phone number, a profile link or a street
address in your own fields is replaced by a marker such as
[removed: email]. Posting text is left alone (a recruiter’s address in a posting is public). The scan works on shapes: it can miss an unusual phone format, it does not know your name, and it does not cover what thegigaicommand prints. Don’t rely on it; keep contact details out of your answers and stories. - The local API answers this computer only. Every request must come from this machine and
carry a
Hostof127.0.0.1:<port>orlocalhost:<port>, so a web page you visit can’t read it through your browser. There is no login: any program you run on this computer can call it.
Example session
Section titled “Example session”A fictional user, Robin, with two profiles (“Backend” and “Platform”). Robin’s words are plain text; what the agent runs is shown under each step.
Robin: What’s new in Scout?
gigai scout new --jsonAgent: 6 new postings across 2 profiles (Backend 4, Platform 2). They are ranked but not assessed. Assessing them is about 6 model calls on your Codex login. Go ahead?
Robin: Yes.
gigai scout new --yes --since 2026-10-01T14:02:00Z --jsongigai scout new --yours --jsonAgent: Assessed 6 of 6. The top three:
Posting Score Needs tailoring Open questions Northwind: Staff Backend Engineer (remote) Needs your answers · 9 of 11 requirements · rank 96 yes: Terraform Have you run Kafka in production? Globex: Platform Engineer (hybrid) Needs your answers · 8 of 11 requirements · rank 91 yes: SOC 2, on-call lead Do you have GCP experience? Initech: Senior SRE (remote) Matched · 7 of 11 requirements · rank 84 yes: Go none Two questions. Have you run Kafka in production?
Robin: Yes, three years at my last job. We moved the order pipeline off a nightly batch onto Kafka and cut the delay from a day to under a minute.
Agent: That is more than a yes. Want me to make this a story? Draft: “Order pipeline moved from a nightly batch to Kafka. Situation: orders were processed once a day. Action: moved the pipeline onto Kafka. Result: delay fell from a day to under a minute.”
Robin: Yes, save it. And GCP: four years, GKE and BigQuery.
Agent: Those two answers make the first assessments of the two jobs old: they were made before you answered, and the jobs’ labels would read “needs attention” until they are assessed again. I can save the answers and assess both jobs again in the same step: 2 model calls. Do that?
Robin: Yes.
gigai scout answer streaming:kafka --question "Have you run Kafka in production?" --answer-text "Yes, three years" --reassess https://jobs.lever.co/northwind/1a2b3c --as agent --jsongigai scout story save --title "Order pipeline moved from nightly batch to Kafka" --raw-text "We moved the order pipeline off a nightly batch onto Kafka and cut the delay from a day to under a minute." --situation "Orders were processed once a day." --action "Moved the pipeline onto Kafka." --result "Delay fell from a day to under a minute." --tag streaming --answers "Tell me about a time you improved a slow process" --as agent --jsongigai scout answer cloud:gcp --question "Do you have GCP experience?" --answer-text "Yes, 4 years, GKE and BigQuery" --reassess https://jobs.lever.co/globex/4d5e6f --as agent --jsongigai scout new --peek --jsonAgent: Saved, and both jobs are assessed again with your answers. Northwind now shows 10 of 11 requirements met; the resume for it is picked from your master, word for word. Globex still does not meet SOC 2.
Robin: Make me the Northwind PDF.
gigai scout resume pdf --job-url https://jobs.lever.co/northwind/1a2b3c --jsonAgent: The PDF is written without your name and contact details. Open this link to add them and download the finished one:
http://127.0.0.1:8765/#/pdf/default/https%3A%2F%2Fjobs.lever.co%2Fnorthwind%2F1a2b3c. Read the resume before you send it.
The agent never asked Robin for a name, an email or a phone number, and never read ~/.gigai.
Screenshots
Section titled “Screenshots”Your agent runs gigai scout new: what is new, and what assessing it would cost, before any model call.
It asks your open questions, saves your answer, and offers to turn an experience into a story.
The same jobs in the Scout UI. (The screenshots below were taken with the pipeline enabled: the Scout label and Scout ATS score appear only in a home that enabled it; it is off by default in 0.1.11.)
Jobs over the per-trigger limit wait for your approval.
What you told your agent is kept once, on this machine, and reused.
The agent’s PDF has no name or contact details. It hands you a link, and you add yours in the browser.
Your master resume, from the terminal: every role and line once, each with its id. On your OK the agent adds a story to it as one line; each profile is offered the new line, never changed by itself.
The companies, postings and person in these images are made up.
Discover the API
Section titled “Discover the API”While Scout runs (default http://127.0.0.1:8765):
GET /apilists every route.GET /api/openapi.jsonis the OpenAPI 3.1 spec (rendered in the API reference).GET /llms.txtis a short plain-text guide.GET /api/jobs?url=returns one job with everything known about it.
B=http://127.0.0.1:8765; J='https://boards.greenhouse.io/acme/jobs/101'curl -s -G "$B/api/jobs" --data-urlencode "url=$J" # one job: posting, assessments, open questions, tailored resumes, linkscurl -s -G "$B/api/jobs/brief" --data-urlencode "url=$J" # the agent's brief, your part (no model call)curl -s -G "$B/api/jobs/brief" --data-urlencode "url=$J" --data-urlencode "part=posting" # its other part: the posting, as datacurl -s -G "$B/api/jobs/suggestions" --data-urlencode "url=$J" # the job's suggestions, as storedcurl -s "$B/api/runs" # every run, newest firstcurl -s -X POST "$B/api/assess" -H 'Content-Type: application/json' \ -d "{\"job\": {\"job_url\": \"$J\"}}" # assess (model call, blocks until done)# POST "$B/api/tailored-resumes" (tailor the resume) is switched off in 0.1.11: it answers tailoring_off.# The resume for the job is the one the assessment picked; its stored form is listed by GET /api/jobs.curl -s -X POST "$B/api/tailored-resumes/pdf" -H 'Content-Type: application/json' \ -d "{\"profile_id\": \"<profile_id>\", \"job_identity\": \"$J\"}" -o resume.pdfThe PDF body takes the profile_id and job_identity of a job’s stored resume (the route and field names keep the old word “tailored”); both
are in the tailored_resumes entries and links.pdf of the GET /api/jobs response.
Errors are {"error": {"code", "message"}}; an unknown_key 422 lists the allowed keys.
The API answers this computer only (loopback peers): Host must be
127.0.0.1:<port> or localhost:<port> (curl sets it), and every write (POST/PUT/DELETE)
needs Content-Type: application/json. Each route and command carries an effect
(read changes nothing, write may change GigAI state) and an external marker
(none offline, model spends a model call and sends text to your model target,
network reads the public internet).
Change a resume and render a new PDF
Section titled “Change a resume and render a new PDF”All of this is local: no model call, no network. GigAI stores no name and no contact details,
so a PDF made by an agent, the CLI or the API has no header: a blank block keeps the page layout.
The reply carries X-GigAI-Finish-Url (the CLI prints it as “Open in Scout to add your name and
contact details and download”), the local Scout page where you type your details in the Generate
PDF form and download the finished PDF. The saved Resume display settings hold only the title
under the name and the layout (spacing, auto fit).
A worked example, an agent changes two bullets and renders a new PDF, for a job that already has a stored (picked) resume:
B=http://127.0.0.1:8765; J='https://boards.greenhouse.io/acme/jobs/101'; P='<profile_id>'H='Content-Type: application/json'
# 1. Read the resume: every body line has an id (L<n>); note updated_at.curl -s -G "$B/api/tailored-resumes" --data-urlencode "profile_id=$P" --data-urlencode "job_identity=$J"
# 2. Change two bullets (one PUT per line; updated_at is the one you read and does not change).curl -s -X PUT "$B/api/tailored-resumes/lines" -H "$H" -d "{\"profile_id\": \"$P\", \"job_identity\": \"$J\", \"updated_at\": \"<updated_at>\", \"line_id\": \"L7\", \"use\": \"custom\", \"text\": \"Rebuilt the scheduling service on Python and Postgres for 4 teams.\"}"curl -s -X PUT "$B/api/tailored-resumes/lines" -H "$H" -d "{\"profile_id\": \"$P\", \"job_identity\": \"$J\", \"updated_at\": \"<updated_at>\", \"line_id\": \"L8\", \"use\": \"custom\", \"text\": \"Ran the release calendar and the on-call rota.\"}"
# 3. Render the new PDF (no header; -D - prints the response headers, X-GigAI-Finish-Url among them).curl -s -D - -X POST "$B/api/tailored-resumes/pdf" -H "$H" -d "{\"profile_id\": \"$P\", \"job_identity\": \"$J\"}" -o resume.pdfThe same with the CLI, which needs no running server for the render:
gigai scout resume pdf --job-url "$J" --out resume.pdf --json # the stored resume, edits included; prints finish_url
# or work on the markdown yourself: edit the two "- " lines in a file, then render itgigai scout resume pdf --in resume.md --out resume.pdf --jsonWhat to know:
- An edited line is marked
kind: customwithorigin: user. It cites no source (refsis empty) and the no-loss check does not cover it: it is your text.edited_fromkeeps the line it replaced, so"use": "original"or"use": "rewritten"brings that back. The UI marks the point “Your words”; Restore on the Changed tab brings the master line back. textis one line of at most 400 characters. Body lines only (a summary, skills or other line, or an entry’s bullet), never an entry heading.- A text that looks like a name line or a contact detail (email, phone, link, street address) is
refused with
422 personal_info_refused: GigAI stores none of those. You add them in the Generate PDF form. - Both PDF routes accept an optional
headerobject (name,email,phone,location,linkedin,link) that fills this one PDF’s header and is never stored, logged or returned. It is there for the Generate PDF form. Details an agent sends in it went through that agent and its model provider first, so an agent should leave it out and hand over the finish link. - Without
--out, the CLI names the file<company>-<role>-<date>.pdf(orresume-<date>.pdffor markdown) in your resumes folder. Your name is never in a file name. POST /api/resume/pdfrenders markdown you send:{"markdown": "...", "spacing_scale": 0.9, "auto_fit": false, "profile_id": "..."}(onlymarkdownis required) answersapplication/pdf, with the page count inX-GigAI-Pages. The markdown is rendered and dropped: not stored, not logged, not sent to a model.- The markdown format is the one a tailored resume’s
markdownfield uses:## Summary,## Experience,## Skills,## Education,## Projects,## Other; in Experience, Projects and Education an entry starts with### <employer, project or school>, may continue with plain heading lines (Staff Engineer | Jun 2020 - Present), and lists-bullets. Trailing<!-- ... -->comments are dropped and lines above the first##are not printed. Text prints as written (inline markdown such as**bold**is not interpreted). Summary lines print as one paragraph and Skills as plain comma-separated lines, four at most, so a summary or other line that was a bullet in your original resume can print differently from the stored tailored resume’s PDF; use--tailored(orPOST /api/tailored-resumes/pdf) when you want exactly that PDF. - Errors are 422s that say what is wrong:
resume_markdown_invalidnames the line number and the rule,resume_markdown_too_largethe limit (65536 bytes),invalid_valueaspacing_scaleoutside 0.7 to 1.4.
Answers and stories: kept once, reused
Section titled “Answers and stories: kept once, reused”The reference for step 3 of the daily workflow. Scout keeps two things you tell your agent, for every profile at once (they are yours, not one profile’s):
- An answer is a short fact a posting asked for: “Do you have GCP experience?” -> “Yes, 4 years, GKE + BigQuery”.
- A story is an experience worth telling: a project, a problem, an outcome. It has a
title, where and when (company,role,period), your own words (raw), a loosely STARnarrative(situation,task,action,result; every part optional),tags, the interview questions it answers (answers_questions) and what triggered it (sources).
Both are local (no model call, no network) and both are what the next assessment uses. An answer
is reused for the same question, and for the same fact worded differently, instead of asking
again. The stories are searched on your machine for each job, and only the few that match the
posting go into that assessment’s prompt as evidence. answers_questions, pooled across your
stories, is the list of questions your stories answer (GET /api/stories/prep).
The usual flow in a chat: the agent asks a job’s open questions. A factual reply is saved as an answer. A reply with substance gets “Want me to make this a story?”: the agent drafts the narrative from your words, shows it, and saves it when you say yes.
You and an agent write the same answers and stories, so every write says who it is (actor:
operator, the default, or agent; a body field, or the X-GigAI-Actor header) and an edit or
a delete sends the revision it read. If it changed since, the reply is 409 revision_conflict
with the current answer or story in the error: read it, merge, send again. Scout’s own page
(Settings > Answers and stories) is read-only: it lists them, shows which jobs used each, and
deletes one that is wrong. It has no form; writing is the agent’s job.
A worked example, an agent saves an answer and a story from a conversation, and later assessments use them:
B=http://127.0.0.1:8765; H='Content-Type: application/json'
# 1. A factual reply: save it as an answer.curl -s -X POST "$B/api/answers" -H "$H" -d '{ "question_id": "cloud:gcp", "question": "Do you have GCP experience?", "answer": "Yes, 4 years, GKE + BigQuery", "actor": "agent"}'# -> 201 {"answer": {"question_id": "cloud:gcp", "written_by": "agent", "revision": 1, "jobs": [], ...}}
# 2. A reply with substance, after "Want me to make this a story?" and a yes: save the story.curl -s -X POST "$B/api/stories" -H "$H" -d '{ "title": "Cut CI time 60% at Acme", "company": "Acme", "role": "Staff Engineer", "period": "2023", "raw": "Our builds took forty minutes, so I moved the runners to Kubernetes and cached the layers.", "narrative": {"situation": "Builds took forty minutes and blocked every merge.", "action": "Moved the runners to Kubernetes and cached the image layers.", "result": "Build time fell 60 percent."}, "tags": ["ci", "delivery"], "answers_questions": ["Tell me about a time you improved a slow process"], "sources": [{"question_id": "tooling:kubernetes"}], "actor": "agent"}'# -> 201 {"story": {"story_id": "story:60_acme_ci_cut_time", "written_by": "agent", "revision": 1, ...}}
# 3. Later, assess another posting that wants GCP and Kubernetes (one model call).curl -s -X POST "$B/api/assess" -H "$H" -d '{"job": {"job_url": "https://boards.greenhouse.io/acme/jobs/101"}}'# -> no question for GCP; that row's resume_evidence reads "Story bank cloud:gcp: Yes, 4 years, ...".# The story matched the posting, so it was in the prompt too: a row may read# "Story bank story:60_acme_ci_cut_time: Cut CI time 60% at Acme ...".
# 4. Each now lists that job: the answer with kind "reused", the story with kind "used".curl -s "$B/api/answers/cloud%3Agcp"curl -s "$B/api/stories/story%3A60_acme_ci_cut_time"
# 5. Improve the story later: send the revision you just read.curl -s -X PUT "$B/api/stories/story%3A60_acme_ci_cut_time" -H "$H" -d '{ "revision": 1, "period": "2022-2023", "actor": "agent"}'The same with the CLI (no running server needed):
gigai scout answers save cloud:gcp --question "Do you have GCP experience?" --answer-text "Yes, 4 years, GKE + BigQuery" --as agent --jsongigai scout answers list --json # every answer, with tags and the jobs that used itgigai scout answers show cloud:gcp --jsongigai scout answers delete cloud:gcp --confirm --revision 1 --jsongigai scout story save --file story.json --as agent --json # the fields of POST /api/storiesgigai scout story list --jsongigai scout story show story:60_acme_ci_cut_time --jsongigai scout story save story:60_acme_ci_cut_time --period 2022-2023 --revision 1 --as agent --jsongigai scout story delete story:60_acme_ci_cut_time --confirm --revision 2 --jsongigai scout story prep --json # the interview questions your stories answergigai scout story prep --job-url URL [--profile ID] --json # one job's rehearsal list: read-only, no model callThe routes: GET / POST /api/answers, GET /api/answers/match, GET / PUT / DELETE /api/answers/{question_id}, GET / POST /api/stories, GET /api/stories/prep, GET / PUT /
DELETE /api/stories/{story_id}. The CLI prints the same bodies.
What to know:
story prep --job-url URLreads the job’s stored assessment (assess it first, or you getassessment_missing); a job has one assessment, so no--profileis needed. Each row lists open questions, a “Tell me about” walkthrough per master line a met row cites, and the stories or answers it cites, withuncoveredtrue when nothing answers a question. Rows that rest only on personal lab lines carrylab. It writes questions, never answers.- Answers from a job page land there too.
POST /api/answerswithreassess(andgigai scout answer --reassess, and the job page’s question box) saves the answer and assesses that job again. Sendquestion(the question’s own words) with it; they are kept with the answer. - Reuse costs nothing extra. The exact same
question_idis reused as before. A question worded differently is settled from the answers in the assessment’s own model call; the row then citesStory bank <id>: ...and the job is listed on the answer or the story. - A run is no longer the way in (0.1.10.7).
POST /api/runis deprecated: it still works for one release, for scripts. Search the stored postings withGET /api/postings(gigai scout jobs list: live, no run, no model call), assess the ones you pick withPOST /api/postings/assess(gigai scout jobs assess: it asks first, with the count and the estimate, and assesses only on approval), and let the background rank them (POST /api/postings/ranksays how far the rank is and ranks on approval:{"mode": "unranked"}the postings not ranked yet,{"mode": "latest"}the newest 100 again in at most 2 calls; withoutapproveit answers the calls it would make and calls no model). Old runs stay readable, andPOST /api/runs/import(gigai scout jobs import-runs) puts what they assessed beside the newer assessments. - A search run reuses it too. The assessments a find-jobs run makes (
POST /api/run, a background check) get whatPOST /api/assessgets: your answers and matching stories, and the run’s own search settings (whether you need sponsorship, the countries you can work from, your location, your target titles). The run’s sealed output says what it used: the assess prompt (prompt_version), a digest of those settings (constraints_digest) and the bank (story_bank: a mark per answer and story, never their text). A posting that did not change is normally not assessed again. It is when the prompt version or those settings changed, when its assessment left a question open and there is an answer or a story about it the run had not seen, or when it cites an answer or story that was edited or deleted.GET /api/runs/{run_id}/resultsand.../postingcarrybank_suggestionsfor the questions that remain. - A run says why it did not assess a posting. Each row a run kept but did not assess has a
reason:
payload.not_assessed[].reasononGET /api/runs/{run_id}/results(for the rows of that page),not_assessed_reasonon.../posting, andnot_assessed_countson.../progress.over_capis a posting the run’s assess cap left out,duplicatea copy of one it kept (same company, title and country),unchangedone whose earlier assessment still stands. The reason never changes which postings the run assessed. - A stored assessment says when it was made with older settings. An assessment made by
POST /api/assess, the job page or “Assess all new” is stored once and read many times. It records what it was made with, as a run does:prompt_version,constraints_digest(sponsorship need, countries, location, work mode) andstory_bank(digests and ids, never the settings or the answers).GET /api/assessmentsitems and thesource: "quick"assessments ofGET /api/jobscarrybasis_stale(true or false) and, when true,basis_stale_reason:older_prompt,settings_changed(the profile’s work mode, countries, location or sponsorship need changed) orstory_bank_changed(an answer or story added or edited since answers one of ITS OWN open questions, by the same id, the near match behindbank_suggestionsor a story about it, or it cites an answer or story that was edited or deleted; answering one question does not flag assessments that asked something else). Astory_bank_changeditem also carriesbasis_stale_bank: the entries that made it stale, each{match: "exact" | "near" | "cited", bank_question_id, bank_question, question_id, question}(ids and question words, never an answer).job_state.assessment_stale.reasoncarries the same reason when that assessment gives the job’s state. The verdict still reads. Each profile is compared with its own settings. - With a master resume, an assessment reads the master. For a profile, the model is shown the
lines of the whole master most relevant to that posting (picked by code, within the same size
limit, in the same one call), not only the profile’s 2-page resume. Such an assessment carries
resume_basis:{input: "evidence", master_revision_id, master_revision, selector_version}; itsresumestill names the profile’s resume. A pasted resume, a profile whose resume was replaced by hand, the assessment of a tailored resume and a find-jobs run read what they read before. - With a master resume, a stored assessment also says when the resume changed for it.
basis_stale_reasonis thenresume_changed, and it is targeted like the answers’ reason: a resume line the assessment quoted as evidence is no longer in what its profile would be assessed with (edited, retired, or no longer in the profile’s resume), or a line that was not there names the subject of one of ITS OWN open questions (tooling:helm: a new line that names Helm). The item carriesbasis_stale_resume: each{change: "line_changed", requirement}or{change: "new_line", question_id, question}(the assessment’s own words, never a resume line).gigai scout resume master initmakes nothing stale: a profile that keeps its resume keeps its assessments. Nothing is assessed again on its own: re-assess the job (POST /api/assess), or answer the “old assessments” question ofgigai scout new. Without a master resume this reason never appears. - Every assessment stored before 0.1.10.7 reads
older_prompt. The assess prompt changed in 0.1.10.7 (posting text is fenced as untrusted), so an assessment made by an earlier version, with or without a recorded basis, is flagged as made with older settings. The verdict still reads, and nothing is assessed again until you ask. - Nothing is re-assessed until you ask. No read calls a model. Re-assess one job with
POST /api/assess({"job": {"job_url": "..."}}), or all of a run’s withPOST /api/runs/{run_id}/assess-all{"start": true}: its queue is the run’s new postings plus the ones with a stale stored assessment, and{}reads the plan (count=new_count+stale_count) without starting anything. A current stored assessment is skipped. - A near match is offered, not assumed. When an assessment still asks something close to
an entry, the response carries
bank_suggestions(also onGET /api/jobs?url=, and for one question onGET /api/answers/match?question_id=&question=): the answer, the question it came from and a score. It is word overlap, no model. To accept it, save it as the answer:POST /api/answers {"question_id": "<the new question>", "answer": "<the suggested answer, or your edit>", "from_bank": "<bank_question_id>", "reassess": {"job_identity": "..."}}. The UI shows it as “We already know: …, use it?”. - Yours, not a profile’s. Since 0.1.10.7 every profile reads the same answers and stories.
The per-profile story bank of 0.1.10.5 and its sharing setting are gone; what it held was moved
once (
gigai scout answers migrate --jsonprints the counts; a second run changes nothing). Two profiles that answered the same question: the newest write is the answer, and a different older one is kept in that answer’shistory. The old file is kept asstory_bank/bank.v1.json. - Tags are model-free:
technical,experience-level,eligibility,education,domain,leadership,conflict,failure,collaboration,system-design,delivery,skill,other, from the id’s category and the question’s words. Set your own withtag. - No contact details. Every write is checked locally: an email, a phone number, a link or a
street address is refused with
422 personal_info_refused(the message names what was found, never the text). The check works on shapes; GigAI has no saved name to compare with, so it does not recognise a name. What a model sees of your answers is a one-line summary per entry, at most 40 entries, redacted again. - Delete (
DELETE /api/answers/<id>?revision=orDELETE /api/stories/<id>?revision=, withContent-Type: application/jsonlike every write) takes it out of use for good. For an answer, the project’s journal keeps the older revision of the record it was in.
The background pipeline
Section titled “The background pipeline”The reference for step 4 of the daily workflow. Off by default in 0.1.11; a home whose settings explicitly enable it keeps it. Where enabled, for a job you engaged with, the pipeline runs four steps: tailor a resume, assess the tailored resume (kept beside the first assessment, never in its place), compute the Scout ATS score, set the Scout label. What Scout’s numbers and labels mean explains the last two.
| Setting (Settings > Background pipeline) | Default |
|---|---|
| Pipeline | off (a home that enabled it keeps it on) |
| Jobs started by one trigger | 10; the rest wait for your approval |
| Pipeline model calls a day | 40 |
Background ranking (rank.enabled, its own switch) |
on, also with the pipeline off; only postings posted in the last 7 days (first stored in them, for a posting with no date) |
| Rank model calls a day, all profiles together | 100, with a warning past 60 |
| Minimum Scout ATS score for “recommended” | 0 (the score is shown, never a gate) |
gigai scout pipeline status --json # jobs, steps, today's countsgigai scout pipeline status --job <job-url> --json # one job's steps and outputsgigai scout pipeline process <job-url> --json # "process now" for one assessed jobgigai scout pipeline cancel <job-url> --jsongigai scout pipeline retry <job-url> --jsongigai scout pipeline approvals list --jsongigai scout pipeline run --once --json # run what waits once, with no Scout servergigai scout metrics --json # what your model calls cost, per kind and modelThe routes: GET /api/pipeline, GET /api/pipeline/job, GET /api/pipeline/approvals,
POST /api/pipeline/approvals/{approval_id}, POST /api/pipeline/process, and the pipeline and
rank blocks of GET / PUT /api/settings/background.
What to know:
- What starts it. Saving or editing an answer or a story (for the jobs whose assessment left that question open), “process now”, and a change to a profile’s resume or search settings (for jobs whose pipeline had finished). Deleting an answer or a story starts nothing.
- A job must be assessed first. The pipeline works from the posting text stored with the job’s assessment and never fetches a posting. A job assessed from pasted text can’t enter it.
- Nothing runs twice. A step whose inputs did not change is skipped: no model call.
- A failed call still counts toward the day’s 40.
- It waits for other work. While a batch of first assessments or a find-jobs run is going, the pipeline waits.
- A resume that is yours is kept. A stored resume the pipeline did not write itself
(you changed a line) is never replaced, not even with
--force. The step finishes withtailor_kept_user_edits, and the assessment, the ATS score and the label use your text. - No contact data. A tailored resume, an ATS line or a keyword that holds a contact shape
fails its step (
contact_data_found), and the pipeline’s own file holds ids, codes and numbers only, no text.
Install and run
Section titled “Install and run”Everything below runs from an installed package (uv tool install gigai),
with no source checkout needed (the first gigai scout run or gigai scout install writes GigAI’s
default settings), and Scout runs from anywhere: no cd into a
target repo and no gigai init step first.
gigai scout install --json # bind, approve, and activate Scoutgigai secrets add exa # optional: only if you turn on Exa, see Configurationgigai scout resume add ./resume.txt --json # import + wrap your resume for find-jobsSee Configuration for the starter find-jobs.json and where Scout lives. Then start it:
gigai scout run --json # installs/activates if needed, starts the API + UI, opens a browser tabgigai scout status --json # running / stopped / crashed / unreachable, with url/pid/log pathgigai scout stop --json # stop it; safe to rerungigai scout run is backgrounded by default: it prints the URL and log
path and returns. Pass --foreground to run it in the current process
instead (Ctrl-C stops it), --no-browser to skip opening a tab, and --port
if 8765 is taken (then use your port in every command that says 8765). Logs live at <home>/logs/scout-<project_id>.log; run
state at <home>/run/scout/<project_id>.json.
If a project has more than one installed, approved Gig, switch which one is active with:
gigai gig use <gig-id> --jsongigai scout install already activates Scout when it’s the only Gig bound,
so this is only needed when switching between Gigs.
Model targets for Scout
Section titled “Model targets for Scout”Scout’s find-jobs resolves a sealed model target (ollama_local, codex_cli,
claude_cli, openrouter_api) to whichever enabled configured target uses that adapter:
gigai setup’s auto-named target (e.g. codex-default or claude-default) just works, no
special naming needed. If you followed an older version of this
documentation and already have a target literally named codex_cli (or
ollama_local/openrouter_api), that still resolves correctly too. Only
having two enabled targets on the same adapter with neither named exactly
the sealed value is an error: disable or remove one (gigai setup or edit
config.toml).
With claude_cli, gigai setup finds claude on your PATH the way it
finds codex, and names the target claude-default. Ranking calls
claude -p in a lean mode (a one-line system prompt; no settings, MCP
servers, slash commands or tools) and passes the target’s model. An
assessment calls it in Claude Code’s plan mode, which ignores --model, so
assessments run Claude Code’s default model whatever the target names.
Without claude on your PATH, ranking is skipped (model_target_unavailable: claude executable is not available on PATH, the same as for a missing
codex) and assessments fail with model_target_unavailable.
Reference
Section titled “Reference”- Scout CLI reference: every
gigai scoutcommand, with its effect and what it may call. - API reference: every route of the local API, from the same spec Scout
serves at
GET /api/openapi.json. - What Scout’s numbers and labels mean: rank, verdict, Scout label, Scout ATS score.
- Privacy and security: what is stored, what is sent, and to whom.
















