job-forge 2.14.4 → 2.14.6

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.
@@ -15,11 +15,6 @@ model_reasoning_effort = "high"
15
15
  model = "gpt-5.4-nano"
16
16
  model_provider = "openai"
17
17
 
18
- [model_providers.openai]
19
- name = "OpenAI"
20
- base_url = "https://api.openai.com/v1"
21
- env_key = "OPENAI_API_KEY"
22
-
23
18
  [mcp_servers.geometra]
24
19
  command = "npx"
25
20
  args = ["-y", "@geometra/mcp"]
@@ -304,6 +304,8 @@ Mode routing is specified in the top-level **## Routing** section. Each mode is
304
304
 
305
305
  ## Offer Verification -- MANDATORY
306
306
 
307
+ **Read local artifacts before the network.** If `reports/` already contains this posting URL (or company+role with a full JD in the body), **Read** that report for verification or evaluation instead of WebFetch/Geometra. If `data/pipeline.md` or `jds/` points at frozen JD text (`local:jds/{file}` or pasted blocks), **Read** that first. Reuse JD text already in the same conversation — do not fetch the same URL twice. (The JD extraction section at the top of `modes/auto-pipeline.md` and its "at most once per session" rule are the detailed contract.)
308
+
307
309
  **When Geometra MCP is available** (interactive sessions), ALWAYS use it to verify offers:
308
310
  1. `geometra_connect` to the URL (via proxy)
309
311
  2. `geometra_page_model` to read structured page content
@@ -317,6 +319,17 @@ Mode routing is specified in the top-level **## Routing** section. Each mode is
317
319
 
318
320
  The goal is to never waste time on closed offers, but also never silently assume a role is active when verification was incomplete.
319
321
 
322
+ ### Canonical MCP tools (quick reference)
323
+
324
+ Pick tools by name directly — reduces unnecessary tool discovery:
325
+
326
+ | Task | Preferred tools |
327
+ |------|------------------|
328
+ | JD from URL | Greenhouse boards API when the URL matches (see JD extraction in `modes/auto-pipeline.md`) → else `geometra_connect` + `geometra_page_model` → else WebFetch → WebSearch last |
329
+ | Offer still live? | Same as JD when Geometra is available; else WebFetch per above |
330
+ | One apply subagent (single job) | One `geometra_connect` per job URL; reuse `sessionId` through schema + fill; submit via atomic `geometra_run_actions` per `modes/apply.md` [H1]. Do **not** `geometra_disconnect` between `geometra_form_schema` and submit on the same form unless recovery requires it |
331
+ | Chromium pool between orchestrator dispatch rounds | `geometra_list_sessions` + `geometra_disconnect({ closeBrowser: true })` per Hard limit [H3] — orchestrator-only; not a substitute for finishing the in-subagent form flow |
332
+
320
333
  ---
321
334
 
322
335
  ## OTP Handling via Gmail MCP -- REQUIRED
package/AGENTS.md CHANGED
@@ -299,6 +299,8 @@ Mode routing is specified in the top-level **## Routing** section. Each mode is
299
299
 
300
300
  ## Offer Verification -- MANDATORY
301
301
 
302
+ **Read local artifacts before the network.** If `reports/` already contains this posting URL (or company+role with a full JD in the body), **Read** that report for verification or evaluation instead of WebFetch/Geometra. If `data/pipeline.md` or `jds/` points at frozen JD text (`local:jds/{file}` or pasted blocks), **Read** that first. Reuse JD text already in the same conversation — do not fetch the same URL twice. (The JD extraction section at the top of `modes/auto-pipeline.md` and its "at most once per session" rule are the detailed contract.)
303
+
302
304
  **When Geometra MCP is available** (interactive sessions), ALWAYS use it to verify offers:
303
305
  1. `geometra_connect` to the URL (via proxy)
304
306
  2. `geometra_page_model` to read structured page content
@@ -312,6 +314,17 @@ Mode routing is specified in the top-level **## Routing** section. Each mode is
312
314
 
313
315
  The goal is to never waste time on closed offers, but also never silently assume a role is active when verification was incomplete.
314
316
 
317
+ ### Canonical MCP tools (quick reference)
318
+
319
+ Pick tools by name directly — reduces unnecessary tool discovery:
320
+
321
+ | Task | Preferred tools |
322
+ |------|------------------|
323
+ | JD from URL | Greenhouse boards API when the URL matches (see JD extraction in `modes/auto-pipeline.md`) → else `geometra_connect` + `geometra_page_model` → else WebFetch → WebSearch last |
324
+ | Offer still live? | Same as JD when Geometra is available; else WebFetch per above |
325
+ | One apply subagent (single job) | One `geometra_connect` per job URL; reuse `sessionId` through schema + fill; submit via atomic `geometra_run_actions` per `modes/apply.md` [H1]. Do **not** `geometra_disconnect` between `geometra_form_schema` and submit on the same form unless recovery requires it |
326
+ | Chromium pool between orchestrator dispatch rounds | `geometra_list_sessions` + `geometra_disconnect({ closeBrowser: true })` per Hard limit [H3] — orchestrator-only; not a substitute for finishing the in-subagent form flow |
327
+
315
328
  ---
316
329
 
317
330
  ## OTP Handling via Gmail MCP -- REQUIRED
package/CLAUDE.md CHANGED
@@ -299,6 +299,8 @@ Mode routing is specified in the top-level **## Routing** section. Each mode is
299
299
 
300
300
  ## Offer Verification -- MANDATORY
301
301
 
302
+ **Read local artifacts before the network.** If `reports/` already contains this posting URL (or company+role with a full JD in the body), **Read** that report for verification or evaluation instead of WebFetch/Geometra. If `data/pipeline.md` or `jds/` points at frozen JD text (`local:jds/{file}` or pasted blocks), **Read** that first. Reuse JD text already in the same conversation — do not fetch the same URL twice. (The JD extraction section at the top of `modes/auto-pipeline.md` and its "at most once per session" rule are the detailed contract.)
303
+
302
304
  **When Geometra MCP is available** (interactive sessions), ALWAYS use it to verify offers:
303
305
  1. `geometra_connect` to the URL (via proxy)
304
306
  2. `geometra_page_model` to read structured page content
@@ -312,6 +314,17 @@ Mode routing is specified in the top-level **## Routing** section. Each mode is
312
314
 
313
315
  The goal is to never waste time on closed offers, but also never silently assume a role is active when verification was incomplete.
314
316
 
317
+ ### Canonical MCP tools (quick reference)
318
+
319
+ Pick tools by name directly — reduces unnecessary tool discovery:
320
+
321
+ | Task | Preferred tools |
322
+ |------|------------------|
323
+ | JD from URL | Greenhouse boards API when the URL matches (see JD extraction in `modes/auto-pipeline.md`) → else `geometra_connect` + `geometra_page_model` → else WebFetch → WebSearch last |
324
+ | Offer still live? | Same as JD when Geometra is available; else WebFetch per above |
325
+ | One apply subagent (single job) | One `geometra_connect` per job URL; reuse `sessionId` through schema + fill; submit via atomic `geometra_run_actions` per `modes/apply.md` [H1]. Do **not** `geometra_disconnect` between `geometra_form_schema` and submit on the same form unless recovery requires it |
326
+ | Chromium pool between orchestrator dispatch rounds | `geometra_list_sessions` + `geometra_disconnect({ closeBrowser: true })` per Hard limit [H3] — orchestrator-only; not a substitute for finishing the in-subagent form flow |
327
+
315
328
  ---
316
329
 
317
330
  ## OTP Handling via Gmail MCP -- REQUIRED
@@ -90,6 +90,24 @@ JobForge can integrate with external systems via opencode hooks. Example hooks:
90
90
 
91
91
  Save hooks in `.opencode/settings.json`.
92
92
 
93
+ ## Application tracker layouts
94
+
95
+ The default harness uses **day-based** tracker files: `data/applications/YYYY-MM-DD.md` (one markdown table per calendar day).
96
+
97
+ Some forks use a **single** `data/applications.md` instead. That is fine if you document it in the project root `AGENTS.md` (or equivalent) and keep `npx job-forge merge` / `verify` aligned with whatever `merge-tracker.mjs` and `verify-pipeline.mjs` expect in your fork.
98
+
99
+ ## Transcript observability (iso-trace)
100
+
101
+ To inspect real agent sessions locally (tool mix, redundant fetches, Geometra churn) without uploading transcripts, use Razroo's [`@razroo/iso-trace`](https://github.com/razroo/iso/tree/main/packages/iso-trace).
102
+
103
+ This harness also ships npm scripts (from the package root): `npm run trace:list`, `npm run trace:stats`, and `npm run trace:show -- <id>` — they wrap `iso-trace` with sensible defaults when the CLI is on `PATH`.
104
+
105
+ **Where Claude Code writes JSONL:** `~/.claude/projects/<encoded-cwd>/*.jsonl`.
106
+
107
+ **CLI (install once per machine):** `npx -y @razroo/iso-trace@latest stats --source "$HOME/.claude/projects/<encoded-dir>/<session>.jsonl"`
108
+
109
+ **Performance:** `iso-trace list --cwd /path/to/repo` walks all of `~/.claude/projects` before filtering; on large machines prefer `stats --source <one.jsonl>` or the library's `discoverSessions({ roots: ["<one encoded project dir>"] })` (see the iso-trace README).
110
+
93
111
  ## States (templates/states.yml)
94
112
 
95
113
  The canonical states rarely need changing. Since `templates/` is a symlink into the harness in consumer projects, adding new states means contributing back to `razroo/JobForge` (see [CONTRIBUTING.md](../CONTRIBUTING.md)). If you're working in the harness repo directly (Path B), update:
@@ -299,6 +299,8 @@ Mode routing is specified in the top-level **## Routing** section. Each mode is
299
299
 
300
300
  ## Offer Verification -- MANDATORY
301
301
 
302
+ **Read local artifacts before the network.** If `reports/` already contains this posting URL (or company+role with a full JD in the body), **Read** that report for verification or evaluation instead of WebFetch/Geometra. If `data/pipeline.md` or `jds/` points at frozen JD text (`local:jds/{file}` or pasted blocks), **Read** that first. Reuse JD text already in the same conversation — do not fetch the same URL twice. (The JD extraction section at the top of `modes/auto-pipeline.md` and its "at most once per session" rule are the detailed contract.)
303
+
302
304
  **When Geometra MCP is available** (interactive sessions), ALWAYS use it to verify offers:
303
305
  1. `geometra_connect` to the URL (via proxy)
304
306
  2. `geometra_page_model` to read structured page content
@@ -312,6 +314,17 @@ Mode routing is specified in the top-level **## Routing** section. Each mode is
312
314
 
313
315
  The goal is to never waste time on closed offers, but also never silently assume a role is active when verification was incomplete.
314
316
 
317
+ ### Canonical MCP tools (quick reference)
318
+
319
+ Pick tools by name directly — reduces unnecessary tool discovery:
320
+
321
+ | Task | Preferred tools |
322
+ |------|------------------|
323
+ | JD from URL | Greenhouse boards API when the URL matches (see JD extraction in `modes/auto-pipeline.md`) → else `geometra_connect` + `geometra_page_model` → else WebFetch → WebSearch last |
324
+ | Offer still live? | Same as JD when Geometra is available; else WebFetch per above |
325
+ | One apply subagent (single job) | One `geometra_connect` per job URL; reuse `sessionId` through schema + fill; submit via atomic `geometra_run_actions` per `modes/apply.md` [H1]. Do **not** `geometra_disconnect` between `geometra_form_schema` and submit on the same form unless recovery requires it |
326
+ | Chromium pool between orchestrator dispatch rounds | `geometra_list_sessions` + `geometra_disconnect({ closeBrowser: true })` per Hard limit [H3] — orchestrator-only; not a substitute for finishing the in-subagent form flow |
327
+
315
328
  ---
316
329
 
317
330
  ## OTP Handling via Gmail MCP -- REQUIRED
package/modes/apply.md CHANGED
@@ -36,6 +36,9 @@ Live application assistant. Reads the active application form in Chrome (via Geo
36
36
  - [D5] Fetch `geometra_form_schema` at most once per application, right after the initial `geometra_connect`. Operate on labels thereafter.
37
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
38
 
39
+ - [D5b] Reuse the same Geometra `sessionId` for every tool call on that job URL until the atomic submit transaction completes (or recovery sequence finishes). Do not `geometra_disconnect` mid-flow between schema and submit unless [H1] recovery forces it.
40
+ why: disconnecting between schema and fill invalidates the SPA session and matches real traces where redundant disconnects outnumbered connects; orchestrator pool cleanup [H3]/[H4] is a separate concern between dispatch rounds, not inside one apply subagent
41
+
39
42
  - [D6] Use `fieldLabel` over `fieldId` everywhere it works.
40
43
  why: labels are stable across DOM refreshes; IDs are regenerated
41
44
 
@@ -21,6 +21,8 @@ Fetch the JD content once. If the input is a **URL** (not pasted JD text), fetch
21
21
 
22
22
  **If the input is JD text** (not a URL): use it directly, no fetching needed.
23
23
 
24
+ **Local artifacts before Step 0 methods:** Grep `reports/` for the URL or stable company+role slug; if a report already embeds the full JD, Read it and skip network fetch entirely. If the pipeline row or `jds/` references `local:jds/{file}`, Read that file first. This stacks with the rule above: one fetch per URL per session, and **zero** if the JD is already on disk.
25
+
24
26
  ## Step 1 — Run Evaluation A-F
25
27
  Execute exactly as in the `offer` mode (read `modes/offer.md` for all blocks A-F).
26
28
 
@@ -34,7 +36,7 @@ Execute the full `pdf` pipeline (read `modes/pdf.md`).
34
36
 
35
37
  Generate draft answers for the application form when the final score is >= 3.5. If the final score is >= 3.5 (per Canonical Scoring Model thresholds in `_shared.md`), generate draft answers for the application form:
36
38
 
37
- 1. **Extract form questions**: Use Geometra MCP (`geometra_connect` + `geometra_form_schema`) to discover all form fields. If questions cannot be extracted, use the generic questions.
39
+ 1. **Extract form questions**: Use Geometra MCP (`geometra_connect` + `geometra_form_schema`) to discover all form fields. **Reuse the same `sessionId` from Step 0** when the apply URL is the same rendered page; only connect again if the prior session ended or the URL changed. If questions cannot be extracted, use the generic questions.
38
40
  2. **Generate answers** following the tone guidelines (see below).
39
41
  3. **Save in the report** as a `## G) Draft Application Answers` section.
40
42
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "job-forge",
3
- "version": "2.14.4",
3
+ "version": "2.14.6",
4
4
  "description": "AI-powered job search pipeline built on opencode",
5
5
  "type": "module",
6
6
  "bin": {
@@ -89,7 +89,7 @@
89
89
  "devDependencies": {
90
90
  "@razroo/iso": "^0.2.5",
91
91
  "@razroo/iso-harness": "^0.6.1",
92
- "@razroo/iso-route": "^0.5.0",
92
+ "@razroo/iso-route": "^0.5.2",
93
93
  "@razroo/iso-trace": "^0.3.1",
94
94
  "@razroo/opencode-model-fallback": "^0.3.1"
95
95
  }