job-forge 2.9.0 → 2.11.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/.claude/agents/general-paid.md +1 -1
- package/.claude/iso-route.resolved.json +5 -4
- package/.codex/config.toml +15 -9
- package/.cursor/iso-route.md +3 -3
- package/.opencode/agents/general-paid.md +1 -1
- package/iso/agents/general-free.md +5 -4
- package/iso/agents/general-paid.md +5 -4
- package/iso/agents/glm-minimal.md +5 -4
- package/models.yaml +27 -60
- package/modes/apply.md +95 -2
- package/opencode.json +4 -4
- package/package.json +8 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: general-paid
|
|
3
3
|
description: Quality-sensitive worker on paid model. Use for offer evaluation narratives (Blocks A-F), cover letter generation, "Why X?" form answers, interview STAR stories, and other tasks where writing quality and judgment matter.
|
|
4
|
-
model: claude-
|
|
4
|
+
model: claude-opus-4-7
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
You are the @general-paid subagent. The orchestrator delegated this task to you because it requires quality writing or judgment — the kind of work `@general-free` isn't well-suited for.
|
|
@@ -4,15 +4,16 @@
|
|
|
4
4
|
"model": "claude-sonnet-4-6"
|
|
5
5
|
},
|
|
6
6
|
"roles": {
|
|
7
|
-
"
|
|
7
|
+
"fast": {
|
|
8
8
|
"provider": "anthropic",
|
|
9
9
|
"model": "claude-haiku-4-5"
|
|
10
10
|
},
|
|
11
|
-
"
|
|
11
|
+
"quality": {
|
|
12
12
|
"provider": "anthropic",
|
|
13
|
-
"model": "claude-
|
|
13
|
+
"model": "claude-opus-4-7",
|
|
14
|
+
"reasoning": "high"
|
|
14
15
|
},
|
|
15
|
-
"
|
|
16
|
+
"minimal": {
|
|
16
17
|
"provider": "anthropic",
|
|
17
18
|
"model": "claude-haiku-4-5"
|
|
18
19
|
}
|
package/.codex/config.toml
CHANGED
|
@@ -2,23 +2,29 @@
|
|
|
2
2
|
model = "claude-sonnet-4-6"
|
|
3
3
|
model_provider = "anthropic"
|
|
4
4
|
|
|
5
|
-
[profiles.
|
|
6
|
-
model = "
|
|
7
|
-
model_provider = "
|
|
5
|
+
[profiles.fast]
|
|
6
|
+
model = "gpt-5.4-mini"
|
|
7
|
+
model_provider = "openai"
|
|
8
8
|
|
|
9
|
-
[profiles.
|
|
10
|
-
model = "
|
|
11
|
-
model_provider = "
|
|
9
|
+
[profiles.quality]
|
|
10
|
+
model = "gpt-5.4"
|
|
11
|
+
model_provider = "openai"
|
|
12
|
+
model_reasoning_effort = "high"
|
|
12
13
|
|
|
13
|
-
[profiles.
|
|
14
|
-
model = "
|
|
15
|
-
model_provider = "
|
|
14
|
+
[profiles.minimal]
|
|
15
|
+
model = "gpt-5.4-nano"
|
|
16
|
+
model_provider = "openai"
|
|
16
17
|
|
|
17
18
|
[model_providers.anthropic]
|
|
18
19
|
name = "Anthropic"
|
|
19
20
|
base_url = "https://api.anthropic.com/v1"
|
|
20
21
|
env_key = "ANTHROPIC_API_KEY"
|
|
21
22
|
|
|
23
|
+
[model_providers.openai]
|
|
24
|
+
name = "OpenAI"
|
|
25
|
+
base_url = "https://api.openai.com/v1"
|
|
26
|
+
env_key = "OPENAI_API_KEY"
|
|
27
|
+
|
|
22
28
|
[mcp_servers.geometra]
|
|
23
29
|
command = "npx"
|
|
24
30
|
args = ["-y", "@geometra/mcp"]
|
package/.cursor/iso-route.md
CHANGED
|
@@ -12,6 +12,6 @@ Cursor has no role/subagent system, so these are advisory — switch the model p
|
|
|
12
12
|
|
|
13
13
|
| Role | Provider | Model | Reasoning |
|
|
14
14
|
| ---- | -------- | ----- | --------- |
|
|
15
|
-
| `
|
|
16
|
-
| `
|
|
17
|
-
| `
|
|
15
|
+
| `fast` | anthropic | `claude-haiku-4-5` | — |
|
|
16
|
+
| `quality` | anthropic | `claude-opus-4-7` | high |
|
|
17
|
+
| `minimal` | anthropic | `claude-haiku-4-5` | — |
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Quality-sensitive worker on paid model. Use for offer evaluation narratives (Blocks A-F), cover letter generation, "Why X?" form answers, interview STAR stories, and other tasks where writing quality and judgment matter.
|
|
3
3
|
mode: subagent
|
|
4
|
-
model: opencode/
|
|
4
|
+
model: opencode-go/kimi-k2.5
|
|
5
5
|
tools:
|
|
6
6
|
geometra_*: false
|
|
7
7
|
gmail_*: false
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Procedural worker on free-tier model. Use for form filling via Geometra, tracker updates, TSV merges, scan dedup, OTP retrieval, and other mechanical/scripted tasks where quality-sensitive text generation is NOT required.
|
|
3
|
+
role: fast
|
|
3
4
|
targets:
|
|
4
|
-
# No inline model: iso-route
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
5
|
+
# No inline model: iso-route's "standard" preset maps role "fast" to
|
|
6
|
+
# each harness's cheapest reliable model. Claude Code reads
|
|
7
|
+
# .claude/iso-route.resolved.json; OpenCode reads opencode.json's
|
|
8
|
+
# agent.fast.model (iso-harness 0.6.0+).
|
|
8
9
|
opencode:
|
|
9
10
|
mode: subagent
|
|
10
11
|
temperature: 0.1
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Quality-sensitive worker on paid model. Use for offer evaluation narratives (Blocks A-F), cover letter generation, "Why X?" form answers, interview STAR stories, and other tasks where writing quality and judgment matter.
|
|
3
|
+
role: quality
|
|
3
4
|
targets:
|
|
4
|
-
# No inline model: iso-route
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
5
|
+
# No inline model: iso-route's "standard" preset maps role "quality" to
|
|
6
|
+
# each harness's top-tier reasoning-capable model. Claude Code reads
|
|
7
|
+
# .claude/iso-route.resolved.json; OpenCode reads opencode.json's
|
|
8
|
+
# agent.quality.model (iso-harness 0.6.0+).
|
|
8
9
|
opencode:
|
|
9
10
|
mode: subagent
|
|
10
11
|
temperature: 0.3
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Narrow-scope extractor on free-tier model. Use for single-purpose tasks where the orchestrator passes the exact input and expects a small, structured output — e.g., "extract these 8 fields from this JD text" or "parse this form schema into a label→type map". NOT for multi-step workflows.
|
|
3
|
+
role: minimal
|
|
3
4
|
targets:
|
|
4
|
-
# No inline model: iso-route
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
5
|
+
# No inline model: iso-route's "standard" preset maps role "minimal" to
|
|
6
|
+
# each harness's smallest credible model. Claude Code reads
|
|
7
|
+
# .claude/iso-route.resolved.json; OpenCode reads opencode.json's
|
|
8
|
+
# agent.minimal.model (iso-harness 0.6.0+).
|
|
8
9
|
opencode:
|
|
9
10
|
mode: subagent
|
|
10
11
|
temperature: 0
|
package/models.yaml
CHANGED
|
@@ -1,63 +1,30 @@
|
|
|
1
|
-
# JobForge model policy
|
|
1
|
+
# JobForge model policy.
|
|
2
2
|
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# - .codex/config.toml (model + [profiles.*] + providers;
|
|
8
|
-
# iso-harness merges [mcp_servers.*]
|
|
9
|
-
# on top of this via v0.5+)
|
|
10
|
-
# - opencode.json (top-level + per-agent overrides;
|
|
11
|
-
# iso-harness preserves these when
|
|
12
|
-
# layering mcp on top)
|
|
13
|
-
# - .cursor/iso-route.md (advisory — Cursor has no
|
|
14
|
-
# programmatic model binding)
|
|
3
|
+
# Extends @razroo/iso-route's bundled "standard" preset — a curated
|
|
4
|
+
# cost-tiered routing config verified against 2026-04 provider catalogs.
|
|
5
|
+
# Preset content lives in node_modules/@razroo/iso-route/presets/standard.yaml;
|
|
6
|
+
# run `npx iso-route plan models.yaml` to see the resolved policy.
|
|
15
7
|
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
# role
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
roles:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
model: claude-haiku-4-5
|
|
38
|
-
targets:
|
|
39
|
-
opencode:
|
|
40
|
-
provider: opencode
|
|
41
|
-
model: opencode/big-pickle
|
|
42
|
-
|
|
43
|
-
# @general-paid — quality-sensitive worker (Blocks A-F evaluation, cover
|
|
44
|
-
# letters, STAR stories, LinkedIn outreach). Upgrade target for
|
|
45
|
-
# high-stakes applies per [D3] in iso/instructions.md.
|
|
46
|
-
general-paid:
|
|
47
|
-
provider: anthropic
|
|
48
|
-
model: claude-sonnet-4-6
|
|
49
|
-
targets:
|
|
50
|
-
opencode:
|
|
51
|
-
provider: opencode
|
|
52
|
-
model: opencode/glm-5.1
|
|
8
|
+
# JobForge's subagents bind to preset roles via the `role:` field in
|
|
9
|
+
# iso/agents/<slug>.md:
|
|
10
|
+
# @general-free → role: fast (Haiku / opencode/big-pickle / gpt-5.4-mini)
|
|
11
|
+
# @general-paid → role: quality (Opus 4.7 / opencode-go/kimi-k2.5 / gpt-5.4)
|
|
12
|
+
# @glm-minimal → role: minimal (Haiku / opencode/minimax-m2.5-free / gpt-5.4-nano)
|
|
13
|
+
#
|
|
14
|
+
# Override anything by adding fields here. For example, to pin Opus on
|
|
15
|
+
# Claude Code for the @general-paid (quality) role:
|
|
16
|
+
#
|
|
17
|
+
# roles:
|
|
18
|
+
# quality:
|
|
19
|
+
# model: claude-opus-4-7
|
|
20
|
+
#
|
|
21
|
+
# Or to route all high-stakes applies to GPT-5.4 on Codex:
|
|
22
|
+
#
|
|
23
|
+
# roles:
|
|
24
|
+
# quality:
|
|
25
|
+
# targets:
|
|
26
|
+
# codex:
|
|
27
|
+
# provider: openai
|
|
28
|
+
# model: gpt-5.4
|
|
53
29
|
|
|
54
|
-
|
|
55
|
-
# for its original tuning target (Minimax on the OpenCode proxy); on
|
|
56
|
-
# harnesses without that proxy it falls through to a cheap general model.
|
|
57
|
-
glm-minimal:
|
|
58
|
-
provider: anthropic
|
|
59
|
-
model: claude-haiku-4-5
|
|
60
|
-
targets:
|
|
61
|
-
opencode:
|
|
62
|
-
provider: opencode
|
|
63
|
-
model: opencode/minimax-m2.5-free
|
|
30
|
+
extends: standard
|
package/modes/apply.md
CHANGED
|
@@ -1,6 +1,99 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Agent: mode-apply
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Live application assistant. Reads the active application form in Chrome (via Geometra MCP), loads prior context from the offer evaluation, generates personalized answers, and submits the form in one atomic transaction. When the user is applying to more than one job, this mode is invoked by the orchestrator as a dispatched subagent — never driven from an interactive session directly.
|
|
4
|
+
|
|
5
|
+
## Hard limits
|
|
6
|
+
|
|
7
|
+
- [H1] Submit the form in a single `geometra_run_actions` call that chains upload + fill + pick + submit. Never split upload / fill / submit across multiple tool calls.
|
|
8
|
+
why: Greenhouse-style forms regenerate internal field IDs after any DOM-mutating action (especially file uploads); multi-call sequences see stale IDs, enter a retry loop, and burn tens of thousands of tokens (4-retry Anthropic FDE trace, ~10K wasted tokens)
|
|
9
|
+
|
|
10
|
+
- [H2] Never auto-retry a failed submit. On recovery failure, report the error to the orchestrator and stop. The orchestrator decides whether to re-dispatch.
|
|
11
|
+
why: duplicate applications are worse than a missed retry — ATS portals often accept a submit whose response was dropped mid-flight, so a retry double-submits. A human must decide.
|
|
12
|
+
|
|
13
|
+
- [H3] Outcomes MUST be written as TSV to `batch/tracker-additions/{num}-{slug}.tsv` — never append APPLIED / FAILED / SKIP to `data/pipeline.md`.
|
|
14
|
+
why: `pipeline.md` is the URL inbox (`[ ]` → `[x]`); TSVs are the bridge to day files via `npx job-forge merge` (see root `[H6]` in iso/instructions.md)
|
|
15
|
+
|
|
16
|
+
- [H4] Before dispatching the first subagent in a multi-job run, the orchestrator MUST call `geometra_list_sessions` then `geometra_disconnect({closeBrowser: true})`. Every dispatch-round, no exceptions.
|
|
17
|
+
why: prior aborted subagents leave Chromium sessions stuck in the pool; next `geometra_connect` fails with "Not connected" (see root `[H3]`)
|
|
18
|
+
|
|
19
|
+
- [H5] Max 2 parallel `task` dispatches per round. For N jobs, run `ceil(N/2)` sequential rounds of 2. Never emit 3+ dispatches in a single message.
|
|
20
|
+
why: free-tier rate limits + subagent post-cleanup cost; racing more than 2 reliably loses at least one result (see root `[H1]`)
|
|
21
|
+
|
|
22
|
+
## Defaults
|
|
23
|
+
|
|
24
|
+
- [D1] Prefer the structured `location_constraints` block in `config/profile.yml` over the prose `location.*` / `compensation.location_flexibility` fields. Fall back to prose only when `location_constraints` is absent.
|
|
25
|
+
why: structured is O(1) field lookup; prose requires LLM interpretation per dispatch. 2026-04-18 empirical: prose path reached the right call but burned interpretation cycles on every candidate.
|
|
26
|
+
|
|
27
|
+
- [D2] When Geometra MCP is unavailable, ask the candidate to share a screenshot, paste form questions as text, or provide company + role for lookup.
|
|
28
|
+
why: Geometra is the expected primary path; gracefully degrade without refusing to help.
|
|
29
|
+
|
|
30
|
+
- [D3] On a detected role change (role on screen ≠ evaluated role in the report), warn the candidate and ask whether to adapt answers or re-evaluate. Do not silently proceed.
|
|
31
|
+
why: adapting answers to the wrong role produces mis-targeted cover letters and the candidate won't catch it until the recruiter does
|
|
32
|
+
|
|
33
|
+
- [D4] Always pass `imeFriendly: true` on `fill_fields` — safe default everywhere, load-bearing for Ashby.
|
|
34
|
+
why: Ashby's React form swallows programmatic text input silently; `imeFriendly: true` fires composition events that clear React's internal validity state. Zero cost on other portals. Confirmed fix: Supabase #793 (2026-04-19).
|
|
35
|
+
|
|
36
|
+
- [D5] Fetch `geometra_form_schema` at most once per application, right after the initial `geometra_connect`. Operate on labels thereafter.
|
|
37
|
+
why: schema re-fetches return hundreds of nested field IDs and pollute context; labels don't change mid-flow, so the second fetch is just paying for the same payload twice
|
|
38
|
+
|
|
39
|
+
- [D6] Use `fieldLabel` over `fieldId` everywhere it works.
|
|
40
|
+
why: labels are stable across DOM refreshes; IDs are regenerated
|
|
41
|
+
|
|
42
|
+
## Procedure
|
|
43
|
+
|
|
44
|
+
1. `geometra_connect` + `geometra_page_model`; avoid re-fetching via WebFetch [D5].
|
|
45
|
+
2. If Geometra is unavailable, ask for screenshot or pasted text [D2].
|
|
46
|
+
3. Extract company + role; Grep `reports/` for a matching evaluation.
|
|
47
|
+
4. Load full report + Section G if present.
|
|
48
|
+
5. Compare role on screen vs evaluated role [D3].
|
|
49
|
+
6. If different, pause for the candidate's decision [D3].
|
|
50
|
+
7. Before dispatch, run Geometra cleanup [H4] and location filter [D1].
|
|
51
|
+
8. Extract form questions; classify each Section-G vs new.
|
|
52
|
+
9. Generate answers from Block B + Block F + Section G + JD.
|
|
53
|
+
10. Submit as ONE `run_actions` call [H1] using labels [D6] with `imeFriendly: true` [D4].
|
|
54
|
+
11. On session error, run the 4-step recovery; only one retry [H2].
|
|
55
|
+
12. On OTP prompt, fetch the code from Gmail via `gmail_get_message`.
|
|
56
|
+
13. Submit the OTP with `geometra_fill_otp` and click Submit.
|
|
57
|
+
14. Write outcome as `batch/tracker-additions/*.tsv` [H3].
|
|
58
|
+
15. Cap parallelism at 2 per round [H5]; one in-flight per company.
|
|
59
|
+
|
|
60
|
+
## Routing
|
|
61
|
+
|
|
62
|
+
| If the role on screen... | Action |
|
|
63
|
+
|---|---|
|
|
64
|
+
| Matches the evaluated report exactly | Proceed with Section G answers |
|
|
65
|
+
| Is a closely related variant (same archetype) | Warn, offer to adapt [D3] |
|
|
66
|
+
| Is materially different (different archetype) | Warn, offer to re-evaluate [D3] |
|
|
67
|
+
| Has no evaluation report | Offer to run auto-pipeline first |
|
|
68
|
+
| Location conflicts with profile.yml constraints | Mark `Discarded`, do not dispatch [D1] |
|
|
69
|
+
| otherwise | Ask the candidate what they want |
|
|
70
|
+
|
|
71
|
+
## Output format
|
|
72
|
+
|
|
73
|
+
The apply subagent returns a short structured message to the orchestrator (not prose to the user):
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
APPLIED <url> — report #NNN, score X.X/5, tenant <ats>
|
|
77
|
+
tracker TSV: batch/tracker-additions/<num>-<slug>.tsv
|
|
78
|
+
notes: <one-line observation>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Or, on failure:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
APPLY FAILED AFTER RECOVERY: <url>
|
|
85
|
+
Error 1: <first error>
|
|
86
|
+
Error 2: <post-recovery error>
|
|
87
|
+
Recommend: re-dispatch on @general-paid
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
# Reference
|
|
93
|
+
|
|
94
|
+
Sections below are the detailed runbooks, decision tables, and portal-specific empirical notes for the rules above. The contract is the `## Hard limits` / `## Defaults` / `## Procedure` / `## Routing` block above; this material is what the subagent consults during execution.
|
|
95
|
+
|
|
96
|
+
## Apply the session-length rule — REQUIRED
|
|
4
97
|
|
|
5
98
|
## Apply the session-length rule — REQUIRED
|
|
6
99
|
|
package/opencode.json
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"$schema": "https://opencode.ai/config.json",
|
|
3
3
|
"model": "opencode/glm-5.1",
|
|
4
4
|
"agent": {
|
|
5
|
-
"
|
|
5
|
+
"fast": {
|
|
6
6
|
"model": "opencode/big-pickle"
|
|
7
7
|
},
|
|
8
|
-
"
|
|
9
|
-
"model": "opencode/
|
|
8
|
+
"quality": {
|
|
9
|
+
"model": "opencode-go/kimi-k2.5"
|
|
10
10
|
},
|
|
11
|
-
"
|
|
11
|
+
"minimal": {
|
|
12
12
|
"model": "opencode/minimax-m2.5-free"
|
|
13
13
|
}
|
|
14
14
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "job-forge",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.11.0",
|
|
4
4
|
"description": "AI-powered job search pipeline built on opencode",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -20,9 +20,14 @@
|
|
|
20
20
|
"tokens:log": "node scripts/token-usage-report.mjs --days 1 --append",
|
|
21
21
|
"trace:list": "iso-trace list --since 7d --cwd .",
|
|
22
22
|
"trace:stats": "iso-trace stats --since 7d --cwd .",
|
|
23
|
+
"trace:show": "iso-trace show",
|
|
24
|
+
"plan": "iso plan .",
|
|
23
25
|
"lint:agentmd": "agentmd lint iso/instructions.md",
|
|
26
|
+
"lint:modes": "isolint lint modes/",
|
|
24
27
|
"test:agentmd": "agentmd test iso/instructions.md --fixtures fixtures/instructions.yml --via claude-code --model claude-haiku-4-5 --concurrency 2",
|
|
25
28
|
"test:agentmd:baseline": "agentmd test iso/instructions.md --fixtures fixtures/instructions.yml --via claude-code --model claude-haiku-4-5 --concurrency 2 --trials 3 --format json --out fixtures/baseline.json",
|
|
29
|
+
"test:agentmd:apply": "agentmd test modes/apply.md --fixtures fixtures/modes/apply.yml --via claude-code --model claude-haiku-4-5 --concurrency 2 --trials 3",
|
|
30
|
+
"lint:agentmd:modes": "agentmd lint modes/apply.md",
|
|
26
31
|
"build:config": "iso build .",
|
|
27
32
|
"prepack": "iso build .",
|
|
28
33
|
"release:check-source": "node ./scripts/release/check-source.mjs",
|
|
@@ -82,9 +87,9 @@
|
|
|
82
87
|
"playwright": "^1.58.1"
|
|
83
88
|
},
|
|
84
89
|
"devDependencies": {
|
|
85
|
-
"@razroo/iso": "^0.2.
|
|
90
|
+
"@razroo/iso": "^0.2.4",
|
|
86
91
|
"@razroo/iso-harness": "^0.6.0",
|
|
87
|
-
"@razroo/iso-route": "^0.
|
|
92
|
+
"@razroo/iso-route": "^0.3.0",
|
|
88
93
|
"@razroo/iso-trace": "^0.1.0"
|
|
89
94
|
}
|
|
90
95
|
}
|