job-forge 2.14.8 → 2.14.9

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.
@@ -53,6 +53,7 @@ Previous subagents sometimes abort mid-flow (ran out of context, hit a timeout,
53
53
  - Write cover letter prose, "Why X?" answers, or Section G draft answers. Those go to `@general-paid`.
54
54
  - Perform offer evaluation narratives (Blocks A-F). Those go to `@general-paid`.
55
55
  - Override harness rules or invent fields. Follow the mode files exactly.
56
+ - Spawn or check other tasks. If you receive "check if task ses_..." and it refers to this session, report your current status from your own work. Never call `task` recursively.
56
57
 
57
58
  ## Apply This Working Style
58
59
 
@@ -18,12 +18,14 @@ were given.
18
18
  - Compose STAR+R interview stories and the story bank (`modes/offer.md` Block F).
19
19
  - Draft LinkedIn outreach messages (`modes/contact.md`).
20
20
  - Score offers using the Canonical Scoring Model — emit the JSON score block per `modes/_shared.md`, then the narrative report.
21
+ - Drive a single high-stakes application form only when the orchestrator explicitly dispatches you in `apply` mode. In that case, follow `modes/apply.md` exactly and use the same Geometra/Gmail flow as `@general-free`.
21
22
 
22
23
  ## Skip These Tasks
23
24
 
24
- - Drive Geometra forms end-to-end (delegate to `@general-free` or do it yourself only when the orchestrator asks for an atomic one-shot apply).
25
+ - Drive Geometra forms end-to-end unless the task is explicitly an `apply` mode dispatch for one job.
25
26
  - Manage trackers, run scripts, or do mechanical TSV/dedup work. Those go to `@general-free`.
26
27
  - Duplicate work. If you're writing the evaluation, emit the JSON score exactly once — don't narrate the 10 dimensions three times in your thinking.
28
+ - Spawn or check other tasks. If you receive "check if task ses_..." and it refers to this session, report your current status from your own work. Never call `task` recursively.
27
29
 
28
30
  ## Apply This Working Style
29
31
 
@@ -52,6 +52,7 @@ Previous subagents sometimes abort mid-flow (ran out of context, hit a timeout,
52
52
  - Write cover letter prose, "Why X?" answers, or Section G draft answers. Those go to `@general-paid`.
53
53
  - Perform offer evaluation narratives (Blocks A-F). Those go to `@general-paid`.
54
54
  - Override harness rules or invent fields. Follow the mode files exactly.
55
+ - Spawn or check other tasks. If you receive "check if task ses_..." and it refers to this session, report your current status from your own work. Never call `task` recursively.
55
56
 
56
57
  ## Apply This Working Style
57
58
 
@@ -17,12 +17,14 @@ were given.
17
17
  - Compose STAR+R interview stories and the story bank (`modes/offer.md` Block F).
18
18
  - Draft LinkedIn outreach messages (`modes/contact.md`).
19
19
  - Score offers using the Canonical Scoring Model — emit the JSON score block per `modes/_shared.md`, then the narrative report.
20
+ - Drive a single high-stakes application form only when the orchestrator explicitly dispatches you in `apply` mode. In that case, follow `modes/apply.md` exactly and use the same Geometra/Gmail flow as `@general-free`.
20
21
 
21
22
  ## Skip These Tasks
22
23
 
23
- - Drive Geometra forms end-to-end (delegate to `@general-free` or do it yourself only when the orchestrator asks for an atomic one-shot apply).
24
+ - Drive Geometra forms end-to-end unless the task is explicitly an `apply` mode dispatch for one job.
24
25
  - Manage trackers, run scripts, or do mechanical TSV/dedup work. Those go to `@general-free`.
25
26
  - Duplicate work. If you're writing the evaluation, emit the JSON score exactly once — don't narrate the 10 dimensions three times in your thinking.
27
+ - Spawn or check other tasks. If you receive "check if task ses_..." and it refers to this session, report your current status from your own work. Never call `task` recursively.
26
28
 
27
29
  ## Apply This Working Style
28
30
 
@@ -9,8 +9,8 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
9
9
 
10
10
  ## Hard limits
11
11
 
12
- - [H1] Max 2 parallel `task` dispatches per message. For N jobs, run `ceil(N/2)` sequential rounds of 2. Applies in all modes, for all user phrasings ("urgent", "apply to 10 jobs now").
13
- why: higher parallelism blows through free-tier rate limits; each subagent requires post-cleanup and racing more than 2 reliably loses at least one result
12
+ - [H1] Max 2 parallel `task` dispatches per message. For N jobs, run `ceil(N/2)` sequential rounds of 2. A round is not complete until both subagents return a final outcome (`APPLIED`, `APPLY FAILED`, `SKIP`, `Discarded`, or a written TSV path). A `task` tool result that only gives a session id / title is a launch acknowledgement, not completion. Applies in all modes, for all user phrasings ("urgent", "apply to 10 jobs now").
13
+ why: higher parallelism blows through free-tier rate limits; each subagent requires post-cleanup and racing more than 2 reliably loses at least one result. On 2026-04-25 the orchestrator launched round 2 while round 1 had only returned task ids, leaving four application subagents in flight and losing two provider-fallback recoveries
14
14
 
15
15
  - [H2] Max 1 application per company+role. Before every `apply` dispatch, grep all four sources for the URL and for `company+role`: `data/pipeline.md`, all `data/applications/*.md` day files, `batch/tracker-additions/*.tsv`, `batch/tracker-additions/merged/*.tsv`. If any source shows APPLIED / Applied, skip the dispatch.
16
16
  why: 2026-04 same-day batch collision — when two batches target the same role, `npx job-forge merge` updates the existing day-file row rather than appending, so grepping day files alone misses earlier-batch applies; merged/*.tsv is the only place the breadcrumb remains
@@ -24,6 +24,9 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
24
24
  - [H5] Re-dispatch the same company only AFTER the previous subagent returns. Never fire the same `task` twice while the first is still in flight.
25
25
  why: two in-flight subagents for the same URL race on Geometra sessions and on tracker TSV writes, corrupting state and sometimes double-submitting
26
26
 
27
+ - [H5b] Do not use `task` to poll task status. If OpenCode returns a task/session id without a final result, record the id, stop dispatching new rounds, and tell the user the round is still in flight. When the user asks to check later, inspect authoritative files (`batch/tracker-additions/*.tsv`, `batch/tracker-additions/merged/*.tsv`, day files, or `iso-trace`) rather than spawning a "check task status" subagent.
28
+ why: OpenCode status prompts can be delivered into the target subagent as a new user message; a 2026-04-25 trace caused a subagent to call `task` recursively instead of finishing the application
29
+
27
30
  - [H6] Application outcomes flow through `batch/tracker-additions/*.tsv`, not `data/pipeline.md`. After any multi-apply run, the orchestrator MUST run `npx job-forge merge` then `npx job-forge verify` before ending the session.
28
31
  why: `pipeline.md` is the URL inbox (`[ ]` pending → `[x]` processed); `data/applications/YYYY-MM-DD.md` is the outcome log; the TSV pathway is the only safe bridge because `merge` handles column order and duplicate detection
29
32
 
@@ -56,7 +59,7 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
56
59
  2. Pick and name the mode from **Routing** [D6]. No match → ask; do not guess.
57
60
  3. Read the active mode file [D3]; decide inline vs delegated work [D1].
58
61
  4. Prepare Geometra dispatches: cleanup [H3], dedupe [H2], location filter [D5], routing [D2].
59
- 5. Dispatch at most 2 tasks per round [H1]; wait per company [H5].
62
+ 5. Dispatch at most 2 tasks per round [H1]; wait for final outcomes, not just task ids [H5b].
60
63
  6. Keep multi-job form-filling out of the orchestrator [H4].
61
64
  7. Cross-check subagent facts against authoritative files [H7].
62
65
  8. Apply score gate [D4].
@@ -14,6 +14,7 @@ tools:
14
14
  geometra_wait_for_resume_parse: true
15
15
  gmail_list_messages: true
16
16
  gmail_get_message: true
17
+ task: false
17
18
  temperature: 0.1
18
19
  reasoningEffort: minimal
19
20
  fallback_models:
@@ -72,6 +73,7 @@ Previous subagents sometimes abort mid-flow (ran out of context, hit a timeout,
72
73
  - Write cover letter prose, "Why X?" answers, or Section G draft answers. Those go to `@general-paid`.
73
74
  - Perform offer evaluation narratives (Blocks A-F). Those go to `@general-paid`.
74
75
  - Override harness rules or invent fields. Follow the mode files exactly.
76
+ - Spawn or check other tasks. If you receive "check if task ses_..." and it refers to this session, report your current status from your own work. Never call `task` recursively.
75
77
 
76
78
  ## Apply This Working Style
77
79
 
@@ -3,8 +3,18 @@ description: Quality-sensitive worker on the strongest free-tier OpenCode model
3
3
  mode: subagent
4
4
  model: openrouter/qwen/qwen3-next-80b-a3b-instruct:free
5
5
  tools:
6
- geometra_*: false
7
- gmail_*: false
6
+ geometra_connect: true
7
+ geometra_page_model: true
8
+ geometra_form_schema: true
9
+ geometra_run_actions: true
10
+ geometra_fill_otp: true
11
+ geometra_upload_files: true
12
+ geometra_list_sessions: true
13
+ geometra_disconnect: true
14
+ geometra_wait_for_resume_parse: true
15
+ gmail_list_messages: true
16
+ gmail_get_message: true
17
+ task: false
8
18
  temperature: 0.3
9
19
  reasoningEffort: medium
10
20
  fallback_models:
@@ -30,12 +40,14 @@ were given.
30
40
  - Compose STAR+R interview stories and the story bank (`modes/offer.md` Block F).
31
41
  - Draft LinkedIn outreach messages (`modes/contact.md`).
32
42
  - Score offers using the Canonical Scoring Model — emit the JSON score block per `modes/_shared.md`, then the narrative report.
43
+ - Drive a single high-stakes application form only when the orchestrator explicitly dispatches you in `apply` mode. In that case, follow `modes/apply.md` exactly and use the same Geometra/Gmail flow as `@general-free`.
33
44
 
34
45
  ## Skip These Tasks
35
46
 
36
- - Drive Geometra forms end-to-end (delegate to `@general-free` or do it yourself only when the orchestrator asks for an atomic one-shot apply).
47
+ - Drive Geometra forms end-to-end unless the task is explicitly an `apply` mode dispatch for one job.
37
48
  - Manage trackers, run scripts, or do mechanical TSV/dedup work. Those go to `@general-free`.
38
49
  - Duplicate work. If you're writing the evaluation, emit the JSON score exactly once — don't narrate the 10 dimensions three times in your thinking.
50
+ - Spawn or check other tasks. If you receive "check if task ses_..." and it refers to this session, report your current status from your own work. Never call `task` recursively.
39
51
 
40
52
  ## Apply This Working Style
41
53
 
@@ -155,7 +155,11 @@ Step 4 — Loop in rounds of 2 (Hard Limit #1)
155
155
  # Dispatch 1 or 2 task() calls in ONE message (never 3+)
156
156
  task(subagent_type=<tier per AGENTS.md routing>, prompt=<apply prompt for pair[0]>)
157
157
  task(subagent_type=<tier>, prompt=<apply prompt for pair[1]>) # only if pair has 2
158
- # WAIT for both subagents to return before proceeding
158
+ # WAIT for both subagents to return final APPLIED / APPLY FAILED / SKIP /
159
+ # Discarded outcomes or TSV paths before proceeding.
160
+ # A returned task/session id is only a launch receipt, not completion.
161
+ # Do not create a "check task status" task; inspect tracker files or
162
+ # iso-trace if the user asks for status later.
159
163
  # Read their return values, log outcomes
160
164
 
161
165
  Step 5 — Between rounds: clean sessions again
package/AGENTS.md CHANGED
@@ -4,8 +4,8 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
4
4
 
5
5
  ## Hard limits
6
6
 
7
- - [H1] Max 2 parallel `task` dispatches per message. For N jobs, run `ceil(N/2)` sequential rounds of 2. Applies in all modes, for all user phrasings ("urgent", "apply to 10 jobs now").
8
- why: higher parallelism blows through free-tier rate limits; each subagent requires post-cleanup and racing more than 2 reliably loses at least one result
7
+ - [H1] Max 2 parallel `task` dispatches per message. For N jobs, run `ceil(N/2)` sequential rounds of 2. A round is not complete until both subagents return a final outcome (`APPLIED`, `APPLY FAILED`, `SKIP`, `Discarded`, or a written TSV path). A `task` tool result that only gives a session id / title is a launch acknowledgement, not completion. Applies in all modes, for all user phrasings ("urgent", "apply to 10 jobs now").
8
+ why: higher parallelism blows through free-tier rate limits; each subagent requires post-cleanup and racing more than 2 reliably loses at least one result. On 2026-04-25 the orchestrator launched round 2 while round 1 had only returned task ids, leaving four application subagents in flight and losing two provider-fallback recoveries
9
9
 
10
10
  - [H2] Max 1 application per company+role. Before every `apply` dispatch, grep all four sources for the URL and for `company+role`: `data/pipeline.md`, all `data/applications/*.md` day files, `batch/tracker-additions/*.tsv`, `batch/tracker-additions/merged/*.tsv`. If any source shows APPLIED / Applied, skip the dispatch.
11
11
  why: 2026-04 same-day batch collision — when two batches target the same role, `npx job-forge merge` updates the existing day-file row rather than appending, so grepping day files alone misses earlier-batch applies; merged/*.tsv is the only place the breadcrumb remains
@@ -19,6 +19,9 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
19
19
  - [H5] Re-dispatch the same company only AFTER the previous subagent returns. Never fire the same `task` twice while the first is still in flight.
20
20
  why: two in-flight subagents for the same URL race on Geometra sessions and on tracker TSV writes, corrupting state and sometimes double-submitting
21
21
 
22
+ - [H5b] Do not use `task` to poll task status. If OpenCode returns a task/session id without a final result, record the id, stop dispatching new rounds, and tell the user the round is still in flight. When the user asks to check later, inspect authoritative files (`batch/tracker-additions/*.tsv`, `batch/tracker-additions/merged/*.tsv`, day files, or `iso-trace`) rather than spawning a "check task status" subagent.
23
+ why: OpenCode status prompts can be delivered into the target subagent as a new user message; a 2026-04-25 trace caused a subagent to call `task` recursively instead of finishing the application
24
+
22
25
  - [H6] Application outcomes flow through `batch/tracker-additions/*.tsv`, not `data/pipeline.md`. After any multi-apply run, the orchestrator MUST run `npx job-forge merge` then `npx job-forge verify` before ending the session.
23
26
  why: `pipeline.md` is the URL inbox (`[ ]` pending → `[x]` processed); `data/applications/YYYY-MM-DD.md` is the outcome log; the TSV pathway is the only safe bridge because `merge` handles column order and duplicate detection
24
27
 
@@ -51,7 +54,7 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
51
54
  2. Pick and name the mode from **Routing** [D6]. No match → ask; do not guess.
52
55
  3. Read the active mode file [D3]; decide inline vs delegated work [D1].
53
56
  4. Prepare Geometra dispatches: cleanup [H3], dedupe [H2], location filter [D5], routing [D2].
54
- 5. Dispatch at most 2 tasks per round [H1]; wait per company [H5].
57
+ 5. Dispatch at most 2 tasks per round [H1]; wait for final outcomes, not just task ids [H5b].
55
58
  6. Keep multi-job form-filling out of the orchestrator [H4].
56
59
  7. Cross-check subagent facts against authoritative files [H7].
57
60
  8. Apply score gate [D4].
package/CLAUDE.md CHANGED
@@ -4,8 +4,8 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
4
4
 
5
5
  ## Hard limits
6
6
 
7
- - [H1] Max 2 parallel `task` dispatches per message. For N jobs, run `ceil(N/2)` sequential rounds of 2. Applies in all modes, for all user phrasings ("urgent", "apply to 10 jobs now").
8
- why: higher parallelism blows through free-tier rate limits; each subagent requires post-cleanup and racing more than 2 reliably loses at least one result
7
+ - [H1] Max 2 parallel `task` dispatches per message. For N jobs, run `ceil(N/2)` sequential rounds of 2. A round is not complete until both subagents return a final outcome (`APPLIED`, `APPLY FAILED`, `SKIP`, `Discarded`, or a written TSV path). A `task` tool result that only gives a session id / title is a launch acknowledgement, not completion. Applies in all modes, for all user phrasings ("urgent", "apply to 10 jobs now").
8
+ why: higher parallelism blows through free-tier rate limits; each subagent requires post-cleanup and racing more than 2 reliably loses at least one result. On 2026-04-25 the orchestrator launched round 2 while round 1 had only returned task ids, leaving four application subagents in flight and losing two provider-fallback recoveries
9
9
 
10
10
  - [H2] Max 1 application per company+role. Before every `apply` dispatch, grep all four sources for the URL and for `company+role`: `data/pipeline.md`, all `data/applications/*.md` day files, `batch/tracker-additions/*.tsv`, `batch/tracker-additions/merged/*.tsv`. If any source shows APPLIED / Applied, skip the dispatch.
11
11
  why: 2026-04 same-day batch collision — when two batches target the same role, `npx job-forge merge` updates the existing day-file row rather than appending, so grepping day files alone misses earlier-batch applies; merged/*.tsv is the only place the breadcrumb remains
@@ -19,6 +19,9 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
19
19
  - [H5] Re-dispatch the same company only AFTER the previous subagent returns. Never fire the same `task` twice while the first is still in flight.
20
20
  why: two in-flight subagents for the same URL race on Geometra sessions and on tracker TSV writes, corrupting state and sometimes double-submitting
21
21
 
22
+ - [H5b] Do not use `task` to poll task status. If OpenCode returns a task/session id without a final result, record the id, stop dispatching new rounds, and tell the user the round is still in flight. When the user asks to check later, inspect authoritative files (`batch/tracker-additions/*.tsv`, `batch/tracker-additions/merged/*.tsv`, day files, or `iso-trace`) rather than spawning a "check task status" subagent.
23
+ why: OpenCode status prompts can be delivered into the target subagent as a new user message; a 2026-04-25 trace caused a subagent to call `task` recursively instead of finishing the application
24
+
22
25
  - [H6] Application outcomes flow through `batch/tracker-additions/*.tsv`, not `data/pipeline.md`. After any multi-apply run, the orchestrator MUST run `npx job-forge merge` then `npx job-forge verify` before ending the session.
23
26
  why: `pipeline.md` is the URL inbox (`[ ]` pending → `[x]` processed); `data/applications/YYYY-MM-DD.md` is the outcome log; the TSV pathway is the only safe bridge because `merge` handles column order and duplicate detection
24
27
 
@@ -51,7 +54,7 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
51
54
  2. Pick and name the mode from **Routing** [D6]. No match → ask; do not guess.
52
55
  3. Read the active mode file [D3]; decide inline vs delegated work [D1].
53
56
  4. Prepare Geometra dispatches: cleanup [H3], dedupe [H2], location filter [D5], routing [D2].
54
- 5. Dispatch at most 2 tasks per round [H1]; wait per company [H5].
57
+ 5. Dispatch at most 2 tasks per round [H1]; wait for final outcomes, not just task ids [H5b].
55
58
  6. Keep multi-job form-filling out of the orchestrator [H4].
56
59
  7. Cross-check subagent facts against authoritative files [H7].
57
60
  8. Apply score gate [D4].
@@ -31,6 +31,7 @@ targets:
31
31
  geometra_wait_for_resume_parse: true
32
32
  gmail_list_messages: true
33
33
  gmail_get_message: true
34
+ task: false
34
35
  ---
35
36
 
36
37
  You are the @general-free subagent. You run on a free-tier model, which means the orchestrator has delegated this task to you **specifically because the work is procedural**: deterministic steps, scripted outputs, no nuanced writing required.
@@ -82,6 +83,7 @@ Previous subagents sometimes abort mid-flow (ran out of context, hit a timeout,
82
83
  - Write cover letter prose, "Why X?" answers, or Section G draft answers. Those go to `@general-paid`.
83
84
  - Perform offer evaluation narratives (Blocks A-F). Those go to `@general-paid`.
84
85
  - Override harness rules or invent fields. Follow the mode files exactly.
86
+ - Spawn or check other tasks. If you receive "check if task ses_..." and it refers to this session, report your current status from your own work. Never call `task` recursively.
85
87
 
86
88
  ## Apply This Working Style
87
89
 
@@ -24,8 +24,18 @@ targets:
24
24
  - openrouter/google/gemma-4-31b-it:free
25
25
  - openrouter/meta-llama/llama-3.3-70b-instruct:free
26
26
  tools:
27
- geometra_*: false
28
- gmail_*: false
27
+ geometra_connect: true
28
+ geometra_page_model: true
29
+ geometra_form_schema: true
30
+ geometra_run_actions: true
31
+ geometra_fill_otp: true
32
+ geometra_upload_files: true
33
+ geometra_list_sessions: true
34
+ geometra_disconnect: true
35
+ geometra_wait_for_resume_parse: true
36
+ gmail_list_messages: true
37
+ gmail_get_message: true
38
+ task: false
29
39
  ---
30
40
 
31
41
  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.
@@ -42,12 +52,14 @@ were given.
42
52
  - Compose STAR+R interview stories and the story bank (`modes/offer.md` Block F).
43
53
  - Draft LinkedIn outreach messages (`modes/contact.md`).
44
54
  - Score offers using the Canonical Scoring Model — emit the JSON score block per `modes/_shared.md`, then the narrative report.
55
+ - Drive a single high-stakes application form only when the orchestrator explicitly dispatches you in `apply` mode. In that case, follow `modes/apply.md` exactly and use the same Geometra/Gmail flow as `@general-free`.
45
56
 
46
57
  ## Skip These Tasks
47
58
 
48
- - Drive Geometra forms end-to-end (delegate to `@general-free` or do it yourself only when the orchestrator asks for an atomic one-shot apply).
59
+ - Drive Geometra forms end-to-end unless the task is explicitly an `apply` mode dispatch for one job.
49
60
  - Manage trackers, run scripts, or do mechanical TSV/dedup work. Those go to `@general-free`.
50
61
  - Duplicate work. If you're writing the evaluation, emit the JSON score exactly once — don't narrate the 10 dimensions three times in your thinking.
62
+ - Spawn or check other tasks. If you receive "check if task ses_..." and it refers to this session, report your current status from your own work. Never call `task` recursively.
51
63
 
52
64
  ## Apply This Working Style
53
65
 
@@ -158,7 +158,11 @@ Step 4 — Loop in rounds of 2 (Hard Limit #1)
158
158
  # Dispatch 1 or 2 task() calls in ONE message (never 3+)
159
159
  task(subagent_type=<tier per AGENTS.md routing>, prompt=<apply prompt for pair[0]>)
160
160
  task(subagent_type=<tier>, prompt=<apply prompt for pair[1]>) # only if pair has 2
161
- # WAIT for both subagents to return before proceeding
161
+ # WAIT for both subagents to return final APPLIED / APPLY FAILED / SKIP /
162
+ # Discarded outcomes or TSV paths before proceeding.
163
+ # A returned task/session id is only a launch receipt, not completion.
164
+ # Do not create a "check task status" task; inspect tracker files or
165
+ # iso-trace if the user asks for status later.
162
166
  # Read their return values, log outcomes
163
167
 
164
168
  Step 5 — Between rounds: clean sessions again
@@ -4,8 +4,8 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
4
4
 
5
5
  ## Hard limits
6
6
 
7
- - [H1] Max 2 parallel `task` dispatches per message. For N jobs, run `ceil(N/2)` sequential rounds of 2. Applies in all modes, for all user phrasings ("urgent", "apply to 10 jobs now").
8
- why: higher parallelism blows through free-tier rate limits; each subagent requires post-cleanup and racing more than 2 reliably loses at least one result
7
+ - [H1] Max 2 parallel `task` dispatches per message. For N jobs, run `ceil(N/2)` sequential rounds of 2. A round is not complete until both subagents return a final outcome (`APPLIED`, `APPLY FAILED`, `SKIP`, `Discarded`, or a written TSV path). A `task` tool result that only gives a session id / title is a launch acknowledgement, not completion. Applies in all modes, for all user phrasings ("urgent", "apply to 10 jobs now").
8
+ why: higher parallelism blows through free-tier rate limits; each subagent requires post-cleanup and racing more than 2 reliably loses at least one result. On 2026-04-25 the orchestrator launched round 2 while round 1 had only returned task ids, leaving four application subagents in flight and losing two provider-fallback recoveries
9
9
 
10
10
  - [H2] Max 1 application per company+role. Before every `apply` dispatch, grep all four sources for the URL and for `company+role`: `data/pipeline.md`, all `data/applications/*.md` day files, `batch/tracker-additions/*.tsv`, `batch/tracker-additions/merged/*.tsv`. If any source shows APPLIED / Applied, skip the dispatch.
11
11
  why: 2026-04 same-day batch collision — when two batches target the same role, `npx job-forge merge` updates the existing day-file row rather than appending, so grepping day files alone misses earlier-batch applies; merged/*.tsv is the only place the breadcrumb remains
@@ -19,6 +19,9 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
19
19
  - [H5] Re-dispatch the same company only AFTER the previous subagent returns. Never fire the same `task` twice while the first is still in flight.
20
20
  why: two in-flight subagents for the same URL race on Geometra sessions and on tracker TSV writes, corrupting state and sometimes double-submitting
21
21
 
22
+ - [H5b] Do not use `task` to poll task status. If OpenCode returns a task/session id without a final result, record the id, stop dispatching new rounds, and tell the user the round is still in flight. When the user asks to check later, inspect authoritative files (`batch/tracker-additions/*.tsv`, `batch/tracker-additions/merged/*.tsv`, day files, or `iso-trace`) rather than spawning a "check task status" subagent.
23
+ why: OpenCode status prompts can be delivered into the target subagent as a new user message; a 2026-04-25 trace caused a subagent to call `task` recursively instead of finishing the application
24
+
22
25
  - [H6] Application outcomes flow through `batch/tracker-additions/*.tsv`, not `data/pipeline.md`. After any multi-apply run, the orchestrator MUST run `npx job-forge merge` then `npx job-forge verify` before ending the session.
23
26
  why: `pipeline.md` is the URL inbox (`[ ]` pending → `[x]` processed); `data/applications/YYYY-MM-DD.md` is the outcome log; the TSV pathway is the only safe bridge because `merge` handles column order and duplicate detection
24
27
 
@@ -51,7 +54,7 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
51
54
  2. Pick and name the mode from **Routing** [D6]. No match → ask; do not guess.
52
55
  3. Read the active mode file [D3]; decide inline vs delegated work [D1].
53
56
  4. Prepare Geometra dispatches: cleanup [H3], dedupe [H2], location filter [D5], routing [D2].
54
- 5. Dispatch at most 2 tasks per round [H1]; wait per company [H5].
57
+ 5. Dispatch at most 2 tasks per round [H1]; wait for final outcomes, not just task ids [H5b].
55
58
  6. Keep multi-job form-filling out of the orchestrator [H4].
56
59
  7. Cross-check subagent facts against authoritative files [H7].
57
60
  8. Apply score gate [D4].
package/modes/apply.md CHANGED
@@ -16,8 +16,8 @@ Live application assistant. Reads the active application form in Chrome (via Geo
16
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
17
  why: prior aborted subagents leave Chromium sessions stuck in the pool; next `geometra_connect` fails with "Not connected" (see root `[H3]`)
18
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]`)
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. Do not start the next round until both current-round subagents return final outcomes (`APPLIED`, `APPLY FAILED`, `SKIP`, `Discarded`, or a written TSV path); task/session ids are only launch receipts.
20
+ why: free-tier rate limits + subagent post-cleanup cost; racing more than 2 reliably loses at least one result (see root `[H1]`). A 2026-04-25 OpenCode trace launched round 2 while round 1 was still running, then lost two fallback recoveries
21
21
 
22
22
  ## Defaults
23
23
 
@@ -42,7 +42,7 @@ Live application assistant. Reads the active application form in Chrome (via Geo
42
42
  - [D6] Use `fieldLabel` over `fieldId` everywhere it works.
43
43
  why: labels are stable across DOM refreshes; IDs are regenerated
44
44
 
45
- - [D7] If the orchestrator's task prompt includes a `proxy` object (sourced from `config/profile.yml`), pass it verbatim into every `geometra_connect` call — including Call 3 of the recovery sequence. If absent, run without one; never invent a proxy URL.
45
+ - [D7] If the orchestrator says a proxy is configured, read the top-level `proxy:` block from `config/profile.yml` and pass that object into every `geometra_connect` call — including Call 3 of the recovery sequence. If the task prompt includes a legacy inline `proxy` object, pass it through, but do not echo credentials in status text. If absent, run without one; never invent a proxy URL.
46
46
  why: class-B Ashby / Cloudflare-fronted portals need a residential outbound IP; the fix is wired in Geometra MCP v1.59.0 but the orchestrator owns the config pipe. See "BYO Residential Proxy" in modes/reference-portals.md.
47
47
 
48
48
  - [D8] Upgrade application routing to `@general-paid` when the offer score is ≥ 4.0/5, the user flags "top-tier", "dream job", or "high-stakes", or the candidate is late-stage/post-screen.
@@ -115,6 +115,13 @@ Sections below are the detailed runbooks, decision tables, and portal-specific e
115
115
 
116
116
  **DO NOT dispatch 3+ `task` calls in one message.** Two is the absolute ceiling. This is non-negotiable, even when the user asks for "apply to 10 jobs" — that becomes 5 rounds of 2, not one message with 10 dispatches.
117
117
 
118
+ **A task/session id is not a result.** If OpenCode gives you a `ses_...`
119
+ id or title after dispatch, do not treat that as the subagent return.
120
+ Do not create another `task` to check it. Stop the round, report the
121
+ in-flight ids, and resume only after a real outcome is visible in the
122
+ subagent return or in an authoritative file (`batch/tracker-additions/`,
123
+ `batch/tracker-additions/merged/`, or the day file).
124
+
118
125
  For a single application interactively, carry on in the current session — the rule targets multi-job loops.
119
126
 
120
127
  ## Apply Preflight — Location Filter (orchestrator runs before dispatch)
@@ -176,7 +183,8 @@ Step 4 — For round in ceil(N/2):
176
183
  # ONE message, 1 or 2 task() calls. Never 3.
177
184
  task(apply to pair[0])
178
185
  task(apply to pair[1]) # only if pair has 2
179
- # WAIT for both returns. Do not proceed until both done.
186
+ # WAIT for both final outcomes. A session id is not completion.
187
+ # Do not dispatch round N+1 while round N is still in flight.
180
188
  Step 5 — Between rounds: geometra_list_sessions() + geometra_disconnect({closeBrowser: true})
181
189
  Step 6 — Reconcile outcomes (Hard Limit #6):
182
190
  bash: npx job-forge merge # TSVs → day file
@@ -188,7 +188,8 @@ Step 2: geometra_disconnect({ closeBrowser: true })
188
188
  Step 3: geometra_connect({ pageUrl: "<the URL the orchestrator gave you>", isolated: true, headless: true, slowMo: 350 })
189
189
  ```
190
190
 
191
- **If the orchestrator passed a `proxy` object in the task prompt** (sourced from `config/profile.yml`), add it to Step 3:
191
+ **If the orchestrator says proxy is configured,** read the top-level
192
+ `proxy:` block from `config/profile.yml` and add it to Step 3:
192
193
 
193
194
  ```
194
195
  Step 3: geometra_connect({
@@ -197,7 +198,7 @@ Step 3: geometra_connect({
197
198
  })
198
199
  ```
199
200
 
200
- Pass the proxy object through unchanged. Do NOT paraphrase or drop fields — `username`/`password`/`bypass` are optional, so only include what the orchestrator gave you. See the "BYO Residential Proxy" reference section for the why.
201
+ Pass the proxy object through unchanged. Do NOT paraphrase or drop fields — `username`/`password`/`bypass` are optional, so only include what exists in `config/profile.yml`. Do not echo proxy credentials in status text. See the "BYO Residential Proxy" reference section for the why.
201
202
 
202
203
  **DO NOT** skip Step 1 or Step 2. **DO NOT** think about whether it's needed. **DO NOT** look at `geometra_list_sessions` output and reason about it — just always call `geometra_disconnect({ closeBrowser: true })` next. The disconnect is a no-op if the pool is empty, and a poison-cure if it isn't.
203
204
 
@@ -75,16 +75,17 @@ See `config/profile.example.yml` for the commented-out template.
75
75
 
76
76
  **Orchestrator responsibilities:**
77
77
 
78
- 1. On session start, read `config/profile.yml` once. If a `proxy:` block is present, capture it as the `PROXY_CONFIG` for the session.
79
- 2. When dispatching any subagent whose work involves a `geometra_connect` call, include `PROXY_CONFIG` verbatim in the task prompt. Example dispatch prompt line: "Pass `proxy: { server: ..., username: ..., password: ..., bypass: ... }` to every `geometra_connect` call you make."
80
- 3. When the orchestrator itself opens a Chromium session (single-application interactive flow), include the same `proxy` object in its own `geometra_connect` call.
78
+ 1. On session start, read `config/profile.yml` once. If a `proxy:` block is present, remember that a proxy is configured, but do not paste username/password values into task prompts or user-visible status.
79
+ 2. When dispatching any subagent whose work involves a `geometra_connect` call, tell it to read `config/profile.yml` and pass the top-level `proxy:` block to every `geometra_connect` call. Example dispatch prompt line: "Proxy is configured; read `config/profile.yml` and pass its top-level `proxy:` object to every `geometra_connect` call."
80
+ 3. When the orchestrator itself opens a Chromium session (single-application interactive flow), include the same `proxy` object from `config/profile.yml` in its own `geometra_connect` call.
81
81
  4. If `proxy:` is absent from `profile.yml`, skip the param entirely. Do NOT invent a proxy URL or leave a stale placeholder.
82
82
 
83
83
  **Subagent responsibilities:**
84
84
 
85
- 1. If the task prompt includes a `proxy` object, pass it through to `geometra_connect` and any `geometra_prepare_browser` calls unchanged.
86
- 2. If the task prompt does NOT include a proxy object, run without one.
87
- 3. Never second-guess the proxy field if the orchestrator sourced it from `profile.yml`, it's authoritative.
85
+ 1. If the task prompt says proxy is configured, read `config/profile.yml` and pass the top-level `proxy:` object through to `geometra_connect` and any `geometra_prepare_browser` calls unchanged.
86
+ 2. If the task prompt includes a legacy inline `proxy` object, pass it through unchanged, but never print the credentials back in status text.
87
+ 3. If the task prompt does NOT mention a proxy and `config/profile.yml` has no `proxy:` block, run without one.
88
+ 4. Never second-guess the proxy field — if it comes from `profile.yml`, it's authoritative.
88
89
 
89
90
  ### When proxy use is load-bearing
90
91
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "job-forge",
3
- "version": "2.14.8",
3
+ "version": "2.14.9",
4
4
  "description": "AI-powered job search pipeline built on opencode",
5
5
  "type": "module",
6
6
  "bin": {