job-forge 2.14.19 → 2.14.21
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/.cursor/rules/main.mdc +4 -1
- package/.opencode/skills/job-forge.md +4 -0
- package/AGENTS.md +4 -1
- package/CLAUDE.md +4 -1
- package/README.md +5 -4
- package/bin/job-forge.mjs +32 -0
- package/docs/ARCHITECTURE.md +3 -0
- package/docs/CUSTOMIZATION.md +4 -0
- package/docs/MODEL-ROUTING.md +2 -0
- package/docs/README.md +1 -1
- package/docs/SETUP.md +1 -0
- package/iso/commands/job-forge.md +4 -0
- package/iso/instructions.md +4 -1
- package/lib/jobforge-context.mjs +55 -0
- package/package.json +7 -1
- package/scripts/context.mjs +180 -0
- package/templates/capabilities.json +1 -0
- package/templates/context.json +292 -0
package/.cursor/rules/main.mdc
CHANGED
|
@@ -68,11 +68,14 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
|
|
|
68
68
|
- [D10] Treat `templates/capabilities.json` as the source of truth for role capability boundaries. Use `npx job-forge capabilities:explain <role>` or `npx job-forge capabilities:check <role> ...` when changing or validating subagent tool/MCP/filesystem/command permissions; do not paste the full capability matrix into task prompts.
|
|
69
69
|
why: executable local policy prevents role-permission drift without adding MCP/tool-schema tokens or loading a capability matrix into the shared prefix
|
|
70
70
|
|
|
71
|
+
- [D11] Treat `templates/context.json` as the source of truth for mode/reference context bundles. Use `npx job-forge context:plan <mode>` or `npx job-forge context:check <mode>` when changing or validating what a mode loads; do not paste the full context matrix into prompts.
|
|
72
|
+
why: deterministic context bundles prevent reference-file drift and accidental token bloat without adding MCP/tool-schema tokens
|
|
73
|
+
|
|
71
74
|
## Procedure
|
|
72
75
|
|
|
73
76
|
1. Check `cv.md`, `profile.yml`, and `portals.yml`; onboard if any file is missing.
|
|
74
77
|
2. Pick and name the mode from **Routing** [D6]. No match → ask; do not guess.
|
|
75
|
-
3. Read the active mode file [D3]; decide inline vs delegated work [D1].
|
|
78
|
+
3. Read the active mode file [D3]; use context bundle checks when changing context loads [D11]; decide inline vs delegated work [D1].
|
|
76
79
|
4. Prepare Geometra dispatches: cleanup [H3], ledger prefilter when present [D8], dedupe [H2], location filter [D5], routing [D2, D10], proxy prompt hygiene [H8].
|
|
77
80
|
5. Dispatch at most 2 tasks per round [H1]; wait for final outcomes, not just task ids [H5b].
|
|
78
81
|
6. Keep multi-job form-filling out of the orchestrator [H4].
|
|
@@ -80,6 +80,10 @@ Artifact contracts (terminal, outside opencode):
|
|
|
80
80
|
Role capabilities (terminal, outside opencode):
|
|
81
81
|
npx job-forge capabilities:explain general-free
|
|
82
82
|
npx job-forge capabilities:check general-free --tool browser --mcp geometra --filesystem write
|
|
83
|
+
|
|
84
|
+
Context bundles (terminal, outside opencode):
|
|
85
|
+
npx job-forge context:plan apply
|
|
86
|
+
npx job-forge context:check apply --budget 23000
|
|
83
87
|
```
|
|
84
88
|
|
|
85
89
|
---
|
package/AGENTS.md
CHANGED
|
@@ -63,11 +63,14 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
|
|
|
63
63
|
- [D10] Treat `templates/capabilities.json` as the source of truth for role capability boundaries. Use `npx job-forge capabilities:explain <role>` or `npx job-forge capabilities:check <role> ...` when changing or validating subagent tool/MCP/filesystem/command permissions; do not paste the full capability matrix into task prompts.
|
|
64
64
|
why: executable local policy prevents role-permission drift without adding MCP/tool-schema tokens or loading a capability matrix into the shared prefix
|
|
65
65
|
|
|
66
|
+
- [D11] Treat `templates/context.json` as the source of truth for mode/reference context bundles. Use `npx job-forge context:plan <mode>` or `npx job-forge context:check <mode>` when changing or validating what a mode loads; do not paste the full context matrix into prompts.
|
|
67
|
+
why: deterministic context bundles prevent reference-file drift and accidental token bloat without adding MCP/tool-schema tokens
|
|
68
|
+
|
|
66
69
|
## Procedure
|
|
67
70
|
|
|
68
71
|
1. Check `cv.md`, `profile.yml`, and `portals.yml`; onboard if any file is missing.
|
|
69
72
|
2. Pick and name the mode from **Routing** [D6]. No match → ask; do not guess.
|
|
70
|
-
3. Read the active mode file [D3]; decide inline vs delegated work [D1].
|
|
73
|
+
3. Read the active mode file [D3]; use context bundle checks when changing context loads [D11]; decide inline vs delegated work [D1].
|
|
71
74
|
4. Prepare Geometra dispatches: cleanup [H3], ledger prefilter when present [D8], dedupe [H2], location filter [D5], routing [D2, D10], proxy prompt hygiene [H8].
|
|
72
75
|
5. Dispatch at most 2 tasks per round [H1]; wait for final outcomes, not just task ids [H5b].
|
|
73
76
|
6. Keep multi-job form-filling out of the orchestrator [H4].
|
package/CLAUDE.md
CHANGED
|
@@ -63,11 +63,14 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
|
|
|
63
63
|
- [D10] Treat `templates/capabilities.json` as the source of truth for role capability boundaries. Use `npx job-forge capabilities:explain <role>` or `npx job-forge capabilities:check <role> ...` when changing or validating subagent tool/MCP/filesystem/command permissions; do not paste the full capability matrix into task prompts.
|
|
64
64
|
why: executable local policy prevents role-permission drift without adding MCP/tool-schema tokens or loading a capability matrix into the shared prefix
|
|
65
65
|
|
|
66
|
+
- [D11] Treat `templates/context.json` as the source of truth for mode/reference context bundles. Use `npx job-forge context:plan <mode>` or `npx job-forge context:check <mode>` when changing or validating what a mode loads; do not paste the full context matrix into prompts.
|
|
67
|
+
why: deterministic context bundles prevent reference-file drift and accidental token bloat without adding MCP/tool-schema tokens
|
|
68
|
+
|
|
66
69
|
## Procedure
|
|
67
70
|
|
|
68
71
|
1. Check `cv.md`, `profile.yml`, and `portals.yml`; onboard if any file is missing.
|
|
69
72
|
2. Pick and name the mode from **Routing** [D6]. No match → ask; do not guess.
|
|
70
|
-
3. Read the active mode file [D3]; decide inline vs delegated work [D1].
|
|
73
|
+
3. Read the active mode file [D3]; use context bundle checks when changing context loads [D11]; decide inline vs delegated work [D1].
|
|
71
74
|
4. Prepare Geometra dispatches: cleanup [H3], ledger prefilter when present [D8], dedupe [H2], location filter [D5], routing [D2, D10], proxy prompt hygiene [H8].
|
|
72
75
|
5. Dispatch at most 2 tasks per round [H1]; wait for final outcomes, not just task ids [H5b].
|
|
73
76
|
6. Keep multi-job form-filling out of the orchestrator [H4].
|
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@ The scaffolded `opencode.json` already has three MCPs wired up — they launch a
|
|
|
31
31
|
- **Gmail** — reads replies from recruiters
|
|
32
32
|
- **state-trace** — typed working memory for cross-session context (resumed batches, recent decisions, repeated portal quirks). Install once with `python3 -m pip install "state-trace[mcp]"`; the MCP command is `state-trace-mcp`.
|
|
33
33
|
|
|
34
|
-
JobForge also keeps MCP-free local workflow state: `templates/contracts.json` defines tracker/apply artifact shapes via `@razroo/iso-contract`, `templates/capabilities.json` defines role capability boundaries via `@razroo/iso-capabilities`, and `.jobforge-ledger/events.jsonl` records deterministic duplicate/status events via `@razroo/iso-ledger`. None of these add prompt or tool-schema tokens.
|
|
34
|
+
JobForge also keeps MCP-free local workflow state: `templates/contracts.json` defines tracker/apply artifact shapes via `@razroo/iso-contract`, `templates/capabilities.json` defines role capability boundaries via `@razroo/iso-capabilities`, `templates/context.json` defines deterministic mode/reference bundles via `@razroo/iso-context`, and `.jobforge-ledger/events.jsonl` records deterministic duplicate/status events via `@razroo/iso-ledger`. None of these add always-on prompt or tool-schema tokens.
|
|
35
35
|
|
|
36
36
|
`npm install` also materializes symlinks for every supported agent harness — OpenCode, Cursor, Claude Code, and Codex — so you can run `opencode`, `cursor`, `claude`, or `codex` in the same project and each picks up the shared MCP config and instructions.
|
|
37
37
|
|
|
@@ -78,7 +78,7 @@ JobForge turns opencode into a full job search command center. Instead of manual
|
|
|
78
78
|
| **Durable Batch Orchestration** | `batch-runner.sh` uses `@razroo/iso-orchestrator` for resumable bundle execution, bounded fan-out, mutexed state writes, and workflow records in `.jobforge-runs/`. |
|
|
79
79
|
| **Pipeline Integrity** | Automated merge, dedup, status normalization, health checks |
|
|
80
80
|
| **Cost-Aware Agent Routing** | Three subagents (`@general-free`, `@general-paid`, `@glm-minimal`) with per-task tool surfaces. On OpenCode, JobForge pins all tiers to `opencode-go/deepseek-v4-flash` so application runs avoid overloaded free-model pools. See [Subagent Routing in AGENTS.md](AGENTS.md) for the task-to-agent mapping. |
|
|
81
|
-
| **Trace + Telemetry + Guard + Contract + Ledger + Capabilities** | `job-forge trace:*` exposes local OpenCode transcripts, `job-forge telemetry:*` summarizes runs, `job-forge guard:*` audits deterministic policy rules, `templates/contracts.json` enforces artifact shape with `iso-contract`, `job-forge ledger:*` queries append-only workflow state,
|
|
81
|
+
| **Trace + Telemetry + Guard + Contract + Ledger + Capabilities + Context** | `job-forge trace:*` exposes local OpenCode transcripts, `job-forge telemetry:*` summarizes runs, `job-forge guard:*` audits deterministic policy rules, `templates/contracts.json` enforces artifact shape with `iso-contract`, `job-forge ledger:*` queries append-only workflow state, `job-forge capabilities:*` checks role boundaries, and `job-forge context:*` plans mode/reference context bundles without MCP/tool-schema overhead. |
|
|
82
82
|
| **Token Cost Visibility** | `job-forge tokens --days 1` for per-session breakdown; `job-forge session-report --since-minutes 60 --log` to flag sessions over budget and append history to `data/token-usage.tsv`. Auto-logged after every batch run. |
|
|
83
83
|
|
|
84
84
|
## Usage
|
|
@@ -162,7 +162,7 @@ my-search/
|
|
|
162
162
|
├── .opencode/skills/job-forge.md # → skill router
|
|
163
163
|
├── .opencode/agents/ # → @general-free, @general-paid, @glm-minimal
|
|
164
164
|
├── modes/ # → _shared.md + skill modes
|
|
165
|
-
├── templates/ # → states.yml, portals.example.yml, cv-template.html, capabilities.json
|
|
165
|
+
├── templates/ # → states.yml, portals.example.yml, cv-template.html, capabilities.json, context.json
|
|
166
166
|
├── batch/batch-prompt.md # → batch worker prompt
|
|
167
167
|
├── batch/batch-runner.sh # → parallel orchestrator
|
|
168
168
|
│
|
|
@@ -188,7 +188,7 @@ JobForge/
|
|
|
188
188
|
│ ├── sync.mjs # postinstall: creates symlinks in consumer project
|
|
189
189
|
│ └── create-job-forge.mjs # scaffolder
|
|
190
190
|
├── modes/ # _shared.md + 16 skill modes
|
|
191
|
-
├── templates/ # cv-template.html, portals.example.yml, states.yml, capabilities.json
|
|
191
|
+
├── templates/ # cv-template.html, portals.example.yml, states.yml, capabilities.json, context.json
|
|
192
192
|
├── config/profile.example.yml # template for consumer's profile.yml
|
|
193
193
|
├── batch/{batch-prompt.md,batch-runner.sh} # batch orchestrator
|
|
194
194
|
├── scripts/
|
|
@@ -196,6 +196,7 @@ JobForge/
|
|
|
196
196
|
│ ├── tracker-line.mjs # iso-contract-backed tracker TSV renderer
|
|
197
197
|
│ ├── ledger.mjs # iso-ledger-backed workflow-state CLI
|
|
198
198
|
│ ├── capabilities.mjs # iso-capabilities-backed role policy CLI
|
|
199
|
+
│ ├── context.mjs # iso-context-backed context bundle CLI
|
|
199
200
|
│ ├── token-usage-report.mjs # opencode cost analyzer
|
|
200
201
|
│ └── release/check-source.mjs # version gate for npm publish
|
|
201
202
|
├── tracker-lib.mjs / merge-tracker.mjs / dedup-tracker.mjs / verify-pipeline.mjs
|
package/bin/job-forge.mjs
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
* guard:* Audit JobForge trace policy with iso-guard
|
|
23
23
|
* ledger:* Query local deterministic workflow state via iso-ledger
|
|
24
24
|
* capabilities:* Query role capability policy via iso-capabilities
|
|
25
|
+
* context:* Query/render deterministic context bundles via iso-context
|
|
25
26
|
* sync Re-run the harness symlink sync (bin/sync.mjs)
|
|
26
27
|
* help, --help Show this message
|
|
27
28
|
*/
|
|
@@ -93,6 +94,15 @@ const capabilitiesAliases = {
|
|
|
93
94
|
'capabilities:path': 'path',
|
|
94
95
|
};
|
|
95
96
|
|
|
97
|
+
const contextAliases = {
|
|
98
|
+
'context:list': 'list',
|
|
99
|
+
'context:explain': 'explain',
|
|
100
|
+
'context:plan': 'plan',
|
|
101
|
+
'context:check': 'check',
|
|
102
|
+
'context:render': 'render',
|
|
103
|
+
'context:path': 'path',
|
|
104
|
+
};
|
|
105
|
+
|
|
96
106
|
const [, , cmd, ...rest] = process.argv;
|
|
97
107
|
|
|
98
108
|
function printHelp() {
|
|
@@ -127,6 +137,11 @@ Commands:
|
|
|
127
137
|
capabilities:explain Explain one role capability policy
|
|
128
138
|
capabilities:check Validate requested tool/MCP/command/fs/network access
|
|
129
139
|
capabilities:render Render compact role guidance for an agent harness
|
|
140
|
+
context:list List JobForge context bundles
|
|
141
|
+
context:explain Explain one context bundle
|
|
142
|
+
context:plan Estimate files/tokens for one context bundle
|
|
143
|
+
context:check Fail if a context bundle exceeds its budget
|
|
144
|
+
context:render Render context bundle content as markdown/json
|
|
130
145
|
sync Re-create harness symlinks in the current project
|
|
131
146
|
|
|
132
147
|
Deterministic helpers (prefer these over LLM-derived values):
|
|
@@ -158,6 +173,8 @@ Pass --help after a command to see its own flags, e.g.:
|
|
|
158
173
|
job-forge ledger:has --company "Acme" --role "Staff Engineer" --status Applied
|
|
159
174
|
job-forge capabilities:explain general-free
|
|
160
175
|
job-forge capabilities:check general-free --tool browser --mcp geometra --command "npx job-forge merge" --filesystem write
|
|
176
|
+
job-forge context:plan apply
|
|
177
|
+
job-forge context:check apply --budget 23000
|
|
161
178
|
|
|
162
179
|
Project directory resolves to $JOB_FORGE_PROJECT or cwd.`);
|
|
163
180
|
}
|
|
@@ -242,6 +259,21 @@ if (cmd === 'capabilities' || capabilitiesAliases[cmd]) {
|
|
|
242
259
|
process.exit(result.status ?? 1);
|
|
243
260
|
}
|
|
244
261
|
|
|
262
|
+
if (cmd === 'context' || contextAliases[cmd]) {
|
|
263
|
+
const contextArgs = cmd === 'context'
|
|
264
|
+
? (rest.length === 0 ? ['help'] : rest)
|
|
265
|
+
: [contextAliases[cmd], ...rest];
|
|
266
|
+
|
|
267
|
+
const scriptPath = join(PKG_ROOT, 'scripts/context.mjs');
|
|
268
|
+
const result = spawnSync(process.execPath, [scriptPath, ...contextArgs], {
|
|
269
|
+
stdio: 'inherit',
|
|
270
|
+
cwd: PROJECT_DIR,
|
|
271
|
+
env: process.env,
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
process.exit(result.status ?? 1);
|
|
275
|
+
}
|
|
276
|
+
|
|
245
277
|
const rel = commands[cmd];
|
|
246
278
|
if (!rel) {
|
|
247
279
|
console.error(`Unknown command: ${cmd}\n`);
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -163,6 +163,7 @@ data/pipeline.md → Pending URLs and `local:jds/...` inbox (see modes/p
|
|
|
163
163
|
.jobforge-ledger/events.jsonl → Append-only workflow events for cheap local duplicate/status checks
|
|
164
164
|
jds/*.md → Saved job descriptions referenced from the pipeline (`local:jds/{file}`)
|
|
165
165
|
templates/states.yml → Canonical status values
|
|
166
|
+
templates/context.json → Deterministic mode/reference context bundle policy
|
|
166
167
|
templates/cv-template.html → PDF generation template
|
|
167
168
|
examples/*.md → Fictional layouts only (not read by scripts; see examples/README.md)
|
|
168
169
|
```
|
|
@@ -176,6 +177,7 @@ Create `data/pipeline.md` when you start using the URL inbox (`/job-forge pipeli
|
|
|
176
177
|
- Tracker TSVs: `batch/tracker-additions/{num}-{company-slug}.tsv` (one file per evaluation; merged files move under `batch/tracker-additions/merged/`; shape enforced by `templates/contracts.json`)
|
|
177
178
|
- Ledger: `.jobforge-ledger/events.jsonl` (created by `job-forge ledger:rebuild`, `tracker-line --write`, or `merge`; gitignored personal state)
|
|
178
179
|
- Capabilities: `templates/capabilities.json` (role boundary policy inspected with `job-forge capabilities:*`)
|
|
180
|
+
- Context: `templates/context.json` (mode/reference file bundles inspected with `job-forge context:*`)
|
|
179
181
|
|
|
180
182
|
## Pipeline Integrity
|
|
181
183
|
|
|
@@ -217,6 +219,7 @@ Scripts maintain data consistency. In a consumer project they're invoked via the
|
|
|
217
219
|
| `scripts/telemetry.mjs` | `npx job-forge telemetry:status` / `telemetry:show` | JobForge operational telemetry derived from OpenCode traces plus tracker TSV state |
|
|
218
220
|
| `scripts/guard.mjs` | `npx job-forge guard:audit` / `guard:explain` | Deterministic `@razroo/iso-guard` policy audits over local OpenCode traces |
|
|
219
221
|
| `scripts/ledger.mjs` | `npx job-forge ledger:status` / `ledger:has` / `ledger:rebuild` | Deterministic `@razroo/iso-ledger` state over tracker, TSV, and pipeline files |
|
|
222
|
+
| `scripts/context.mjs` | `npx job-forge context:list` / `context:plan` / `context:check` / `context:render` | Deterministic `@razroo/iso-context` mode/reference context bundle planning and rendering |
|
|
220
223
|
| `tracker-lib.mjs` | _(library)_ | Shared helpers for reading/writing day-based tracker files — imported by merge/dedup/verify/normalize |
|
|
221
224
|
| `bin/sync.mjs` | `npx job-forge sync` | Creates the harness symlinks in a consumer project (also runs as `postinstall`) |
|
|
222
225
|
| `bin/create-job-forge.mjs` | `npx create-job-forge <dir>` | Scaffolds a new personal project |
|
package/docs/CUSTOMIZATION.md
CHANGED
|
@@ -146,6 +146,10 @@ Machine-readable artifact shapes live in `templates/contracts.json` and are enfo
|
|
|
146
146
|
|
|
147
147
|
Role capability boundaries live in `templates/capabilities.json` and are enforced locally by `@razroo/iso-capabilities`. Use `job-forge capabilities:explain <role>` to inspect a role and `job-forge capabilities:check <role> ...` to validate a tool, MCP, command, filesystem, or network boundary before changing agent frontmatter. Custom forks can extend the policy, but keep it aligned with `.opencode/agents/` and the routing rules in `iso/instructions.md`.
|
|
148
148
|
|
|
149
|
+
## JobForge context bundles
|
|
150
|
+
|
|
151
|
+
Mode/reference context bundles live in `templates/context.json` and are planned locally by `@razroo/iso-context`. Use `job-forge context:plan <mode>` to see the files and estimated tokens, `job-forge context:check <mode>` to fail on budget drift, and `job-forge context:render <mode>` when you intentionally need a compact markdown or JSON context bundle. This is not an MCP and does not add tool-schema tokens; rendered context only consumes prompt tokens when a workflow deliberately asks for it.
|
|
152
|
+
|
|
149
153
|
## JobForge guard audits
|
|
150
154
|
|
|
151
155
|
Guard audits run deterministic `@razroo/iso-guard` policies over the same local OpenCode traces. The default policy lives at `templates/guards/jobforge-baseline.yaml` and checks rules that are reliable from transcript data, including max two task dispatches per assistant message, no task-status polling via `task`, no raw proxy configuration in task prompts, and no child session task recursion.
|
package/docs/MODEL-ROUTING.md
CHANGED
|
@@ -55,6 +55,8 @@ Disables ~30 MCP tool schemas globally; each agent re-enables only what it needs
|
|
|
55
55
|
|
|
56
56
|
`templates/capabilities.json` is the executable source for intended role boundaries. Inspect it with `job-forge capabilities:explain general-free`, or validate a boundary with `job-forge capabilities:check general-free --tool browser --mcp geometra --command "npx job-forge merge" --filesystem write --network restricted`. Native harness frontmatter still enforces permissions where supported; `iso-capabilities` gives JobForge a local audit/check contract for changes and reviews.
|
|
57
57
|
|
|
58
|
+
`templates/context.json` is the executable source for intended mode/reference context loads. Inspect a bundle with `job-forge context:plan apply`, fail CI or local reviews on drift with `job-forge context:check apply`, or render the bundle only when a workflow deliberately needs it. `iso-context` is local CLI/library policy, not an MCP, so it avoids tool-schema overhead and prevents accidental "load every mode file" prompt bloat.
|
|
59
|
+
|
|
58
60
|
**3. Thinking budgets** (`reasoningEffort` in agent frontmatter):
|
|
59
61
|
- `@general-free`: `minimal` — procedural work shouldn't need chain-of-thought
|
|
60
62
|
- `@general-paid`: `medium` — writing quality benefits from thinking
|
package/docs/README.md
CHANGED
|
@@ -31,7 +31,7 @@ The harness exposes a single CLI (`job-forge`) installed as a `bin` entry. In a
|
|
|
31
31
|
|
|
32
32
|
| What you need | Where to read |
|
|
33
33
|
|---------------|---------------|
|
|
34
|
-
| Full command list (`verify`, `merge`, `dedup`, `normalize`, `pdf`, `sync-check`, `tokens`, `trace`, `telemetry`, `guard`, `ledger`, `sync`). | [SETUP.md — Tracker and scripts (terminal)](SETUP.md#tracker-and-scripts-terminal). |
|
|
34
|
+
| Full command list (`verify`, `merge`, `dedup`, `normalize`, `pdf`, `sync-check`, `tokens`, `trace`, `telemetry`, `guard`, `ledger`, `context`, `sync`). | [SETUP.md — Tracker and scripts (terminal)](SETUP.md#tracker-and-scripts-terminal). |
|
|
35
35
|
| What each harness `.mjs` script does. | [ARCHITECTURE.md — Pipeline integrity](ARCHITECTURE.md#pipeline-integrity) and the scripts table underneath. |
|
|
36
36
|
| Batch runner, TSV layout, and `batch/tracker-additions/` merge flow. | [batch/README.md](../batch/README.md). |
|
|
37
37
|
| PR gate for harness contributions (`npm run verify` + `npm run build:dashboard`). | [CONTRIBUTING.md — Development](../CONTRIBUTING.md#development). |
|
package/docs/SETUP.md
CHANGED
|
@@ -127,6 +127,7 @@ From your project root, these commands maintain the tracker and pipeline checks.
|
|
|
127
127
|
| Merge `batch/tracker-additions/*.tsv` into the tracker | `npx job-forge merge` | `npm run merge` |
|
|
128
128
|
| Inspect tracker row contract | `npx iso-contract explain jobforge.tracker-row --contracts templates/contracts.json` | _(none)_ |
|
|
129
129
|
| Inspect role capabilities | `npx job-forge capabilities:explain general-free` | `npm run capabilities:explain -- general-free` |
|
|
130
|
+
| Inspect context bundle budget | `npx job-forge context:plan apply` | `npm run context:plan -- apply` |
|
|
130
131
|
| Map status column to canonical labels | `npx job-forge normalize` | `npm run normalize` |
|
|
131
132
|
| Merge duplicate company/role rows | `npx job-forge dedup` | `npm run dedup` |
|
|
132
133
|
| Generate ATS-optimized CV PDF | `npx job-forge pdf` | `npm run pdf` |
|
|
@@ -83,6 +83,10 @@ Artifact contracts (terminal, outside opencode):
|
|
|
83
83
|
Role capabilities (terminal, outside opencode):
|
|
84
84
|
npx job-forge capabilities:explain general-free
|
|
85
85
|
npx job-forge capabilities:check general-free --tool browser --mcp geometra --filesystem write
|
|
86
|
+
|
|
87
|
+
Context bundles (terminal, outside opencode):
|
|
88
|
+
npx job-forge context:plan apply
|
|
89
|
+
npx job-forge context:check apply --budget 23000
|
|
86
90
|
```
|
|
87
91
|
|
|
88
92
|
---
|
package/iso/instructions.md
CHANGED
|
@@ -63,11 +63,14 @@ AI-powered job search pipeline: scans portals, evaluates offers, generates CVs v
|
|
|
63
63
|
- [D10] Treat `templates/capabilities.json` as the source of truth for role capability boundaries. Use `npx job-forge capabilities:explain <role>` or `npx job-forge capabilities:check <role> ...` when changing or validating subagent tool/MCP/filesystem/command permissions; do not paste the full capability matrix into task prompts.
|
|
64
64
|
why: executable local policy prevents role-permission drift without adding MCP/tool-schema tokens or loading a capability matrix into the shared prefix
|
|
65
65
|
|
|
66
|
+
- [D11] Treat `templates/context.json` as the source of truth for mode/reference context bundles. Use `npx job-forge context:plan <mode>` or `npx job-forge context:check <mode>` when changing or validating what a mode loads; do not paste the full context matrix into prompts.
|
|
67
|
+
why: deterministic context bundles prevent reference-file drift and accidental token bloat without adding MCP/tool-schema tokens
|
|
68
|
+
|
|
66
69
|
## Procedure
|
|
67
70
|
|
|
68
71
|
1. Check `cv.md`, `profile.yml`, and `portals.yml`; onboard if any file is missing.
|
|
69
72
|
2. Pick and name the mode from **Routing** [D6]. No match → ask; do not guess.
|
|
70
|
-
3. Read the active mode file [D3]; decide inline vs delegated work [D1].
|
|
73
|
+
3. Read the active mode file [D3]; use context bundle checks when changing context loads [D11]; decide inline vs delegated work [D1].
|
|
71
74
|
4. Prepare Geometra dispatches: cleanup [H3], ledger prefilter when present [D8], dedupe [H2], location filter [D5], routing [D2, D10], proxy prompt hygiene [H8].
|
|
72
75
|
5. Dispatch at most 2 tasks per round [H1]; wait for final outcomes, not just task ids [H5b].
|
|
73
76
|
6. Keep multi-job form-filling out of the orchestrator [H4].
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'fs';
|
|
2
|
+
import { dirname, join, resolve } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import {
|
|
5
|
+
bundleNames,
|
|
6
|
+
formatContextPlan,
|
|
7
|
+
formatResolvedContextBundle,
|
|
8
|
+
loadContextPolicy,
|
|
9
|
+
planContext,
|
|
10
|
+
renderContextPlan,
|
|
11
|
+
resolveContextBundle,
|
|
12
|
+
} from '@razroo/iso-context';
|
|
13
|
+
|
|
14
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
const PKG_ROOT = resolve(__dirname, '..');
|
|
16
|
+
export const CONTEXT_RELATIVE_PATH = 'templates/context.json';
|
|
17
|
+
|
|
18
|
+
export function resolveProjectDir(projectDir = process.env.JOB_FORGE_PROJECT || process.cwd()) {
|
|
19
|
+
return projectDir;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function jobForgeContextPath(projectDir = resolveProjectDir()) {
|
|
23
|
+
const projectPath = join(projectDir, CONTEXT_RELATIVE_PATH);
|
|
24
|
+
if (existsSync(projectPath)) return projectPath;
|
|
25
|
+
return join(PKG_ROOT, CONTEXT_RELATIVE_PATH);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function loadJobForgeContextPolicy(projectDir = resolveProjectDir()) {
|
|
29
|
+
const path = jobForgeContextPath(projectDir);
|
|
30
|
+
return loadContextPolicy(JSON.parse(readFileSync(path, 'utf-8')));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function listJobForgeContextBundles(projectDir = resolveProjectDir()) {
|
|
34
|
+
return bundleNames(loadJobForgeContextPolicy(projectDir));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function resolveJobForgeContextBundle(name, projectDir = resolveProjectDir()) {
|
|
38
|
+
return resolveContextBundle(loadJobForgeContextPolicy(projectDir), name);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function planJobForgeContextBundle(name, options = {}, projectDir = resolveProjectDir()) {
|
|
42
|
+
return planContext(loadJobForgeContextPolicy(projectDir), name, options);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function formatJobForgeContextPlan(plan) {
|
|
46
|
+
return formatContextPlan(plan);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function formatJobForgeContextBundle(bundle) {
|
|
50
|
+
return formatResolvedContextBundle(bundle);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function renderJobForgeContextPlan(plan, target = 'markdown') {
|
|
54
|
+
return renderContextPlan(plan, target);
|
|
55
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "job-forge",
|
|
3
|
-
"version": "2.14.
|
|
3
|
+
"version": "2.14.21",
|
|
4
4
|
"description": "AI-powered job search pipeline built on opencode",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -36,6 +36,11 @@
|
|
|
36
36
|
"capabilities:explain": "node bin/job-forge.mjs capabilities:explain",
|
|
37
37
|
"capabilities:check": "node bin/job-forge.mjs capabilities:check",
|
|
38
38
|
"capabilities:render": "node bin/job-forge.mjs capabilities:render",
|
|
39
|
+
"context:list": "node bin/job-forge.mjs context:list",
|
|
40
|
+
"context:explain": "node bin/job-forge.mjs context:explain",
|
|
41
|
+
"context:plan": "node bin/job-forge.mjs context:plan",
|
|
42
|
+
"context:check": "node bin/job-forge.mjs context:check",
|
|
43
|
+
"context:render": "node bin/job-forge.mjs context:render",
|
|
39
44
|
"plan": "iso plan .",
|
|
40
45
|
"lint:agentmd": "agentmd lint iso/instructions.md",
|
|
41
46
|
"lint:modes": "isolint lint modes/",
|
|
@@ -101,6 +106,7 @@
|
|
|
101
106
|
},
|
|
102
107
|
"dependencies": {
|
|
103
108
|
"@razroo/iso-capabilities": "^0.1.0",
|
|
109
|
+
"@razroo/iso-context": "^0.1.0",
|
|
104
110
|
"@razroo/iso-contract": "^0.1.0",
|
|
105
111
|
"@razroo/iso-guard": "^0.1.0",
|
|
106
112
|
"@razroo/iso-ledger": "^0.1.0",
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { PROJECT_DIR } from '../tracker-lib.mjs';
|
|
4
|
+
import {
|
|
5
|
+
formatJobForgeContextBundle,
|
|
6
|
+
formatJobForgeContextPlan,
|
|
7
|
+
jobForgeContextPath,
|
|
8
|
+
listJobForgeContextBundles,
|
|
9
|
+
planJobForgeContextBundle,
|
|
10
|
+
renderJobForgeContextPlan,
|
|
11
|
+
resolveJobForgeContextBundle,
|
|
12
|
+
} from '../lib/jobforge-context.mjs';
|
|
13
|
+
|
|
14
|
+
const USAGE = `job-forge context - deterministic mode/reference context policy
|
|
15
|
+
|
|
16
|
+
Usage:
|
|
17
|
+
job-forge context:list [--json]
|
|
18
|
+
job-forge context:explain <bundle> [--json]
|
|
19
|
+
job-forge context:plan <bundle> [--root <dir>] [--budget N] [--chars-per-token N] [--json]
|
|
20
|
+
job-forge context:check <bundle> [--root <dir>] [--budget N] [--chars-per-token N] [--json]
|
|
21
|
+
job-forge context:render <bundle> [--root <dir>] [--target markdown|json] [--json]
|
|
22
|
+
job-forge context:path
|
|
23
|
+
|
|
24
|
+
The policy is templates/context.json. It is local project policy, not an MCP
|
|
25
|
+
and not always-loaded prompt context.`;
|
|
26
|
+
|
|
27
|
+
const [cmd = 'help', ...rawArgs] = process.argv.slice(2);
|
|
28
|
+
const { positional, opts } = parseArgs(rawArgs);
|
|
29
|
+
|
|
30
|
+
if (opts.help || cmd === 'help' || cmd === '--help' || cmd === '-h') {
|
|
31
|
+
console.log(USAGE);
|
|
32
|
+
process.exit(0);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
if (cmd === 'path') {
|
|
37
|
+
console.log(jobForgeContextPath(PROJECT_DIR));
|
|
38
|
+
} else if (cmd === 'list') {
|
|
39
|
+
list(opts);
|
|
40
|
+
} else if (cmd === 'explain') {
|
|
41
|
+
explain(positional, opts);
|
|
42
|
+
} else if (cmd === 'plan') {
|
|
43
|
+
plan(positional, opts, false);
|
|
44
|
+
} else if (cmd === 'check') {
|
|
45
|
+
check(positional, opts);
|
|
46
|
+
} else if (cmd === 'render') {
|
|
47
|
+
render(positional, opts);
|
|
48
|
+
} else {
|
|
49
|
+
console.error(`unknown context command "${cmd}"\n`);
|
|
50
|
+
console.error(USAGE);
|
|
51
|
+
process.exit(2);
|
|
52
|
+
}
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function parseArgs(args) {
|
|
59
|
+
const positional = [];
|
|
60
|
+
const opts = {
|
|
61
|
+
json: false,
|
|
62
|
+
help: false,
|
|
63
|
+
target: 'markdown',
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
for (let i = 0; i < args.length; i++) {
|
|
67
|
+
const arg = args[i];
|
|
68
|
+
if (arg === '--json') {
|
|
69
|
+
opts.json = true;
|
|
70
|
+
} else if (arg === '--root') {
|
|
71
|
+
opts.root = valueAfter(args, ++i, '--root');
|
|
72
|
+
} else if (arg.startsWith('--root=')) {
|
|
73
|
+
opts.root = arg.slice('--root='.length);
|
|
74
|
+
} else if (arg === '--budget' || arg === '--token-budget') {
|
|
75
|
+
opts.tokenBudget = parsePositiveInteger(valueAfter(args, ++i, arg), arg);
|
|
76
|
+
} else if (arg.startsWith('--budget=')) {
|
|
77
|
+
opts.tokenBudget = parsePositiveInteger(arg.slice('--budget='.length), '--budget');
|
|
78
|
+
} else if (arg.startsWith('--token-budget=')) {
|
|
79
|
+
opts.tokenBudget = parsePositiveInteger(arg.slice('--token-budget='.length), '--token-budget');
|
|
80
|
+
} else if (arg === '--chars-per-token') {
|
|
81
|
+
opts.charsPerToken = parsePositiveInteger(valueAfter(args, ++i, '--chars-per-token'), '--chars-per-token');
|
|
82
|
+
} else if (arg.startsWith('--chars-per-token=')) {
|
|
83
|
+
opts.charsPerToken = parsePositiveInteger(arg.slice('--chars-per-token='.length), '--chars-per-token');
|
|
84
|
+
} else if (arg === '--target') {
|
|
85
|
+
opts.target = parseTarget(valueAfter(args, ++i, '--target'));
|
|
86
|
+
} else if (arg.startsWith('--target=')) {
|
|
87
|
+
opts.target = parseTarget(arg.slice('--target='.length));
|
|
88
|
+
} else if (arg === '--help' || arg === '-h') {
|
|
89
|
+
opts.help = true;
|
|
90
|
+
} else if (arg.startsWith('--')) {
|
|
91
|
+
throw new Error(`unknown flag "${arg}"`);
|
|
92
|
+
} else {
|
|
93
|
+
positional.push(arg);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return { positional, opts };
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function valueAfter(values, index, flag) {
|
|
101
|
+
const value = values[index];
|
|
102
|
+
if (!value || value.startsWith('--')) throw new Error(`${flag} requires a value`);
|
|
103
|
+
return value;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function list(opts) {
|
|
107
|
+
const names = listJobForgeContextBundles(PROJECT_DIR);
|
|
108
|
+
if (opts.json) {
|
|
109
|
+
console.log(JSON.stringify(names, null, 2));
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
console.log(names.join('\n'));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function explain(positional, opts) {
|
|
116
|
+
const bundle = readBundle(positional);
|
|
117
|
+
if (opts.json) {
|
|
118
|
+
console.log(JSON.stringify(bundle, null, 2));
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
console.log(formatJobForgeContextBundle(bundle));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function plan(positional, opts, includeContent) {
|
|
125
|
+
const bundleName = readBundleName(positional);
|
|
126
|
+
const result = planJobForgeContextBundle(bundleName, planOptions(opts, includeContent), PROJECT_DIR);
|
|
127
|
+
if (opts.json) {
|
|
128
|
+
console.log(JSON.stringify(result, null, 2));
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
131
|
+
console.log(formatJobForgeContextPlan(result));
|
|
132
|
+
return result;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function check(positional, opts) {
|
|
136
|
+
const result = plan(positional, opts, false);
|
|
137
|
+
process.exit(result.ok ? 0 : 1);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function render(positional, opts) {
|
|
141
|
+
const bundleName = readBundleName(positional);
|
|
142
|
+
const result = planJobForgeContextBundle(bundleName, planOptions(opts, true), PROJECT_DIR);
|
|
143
|
+
const text = renderJobForgeContextPlan(result, opts.target);
|
|
144
|
+
if (opts.json) {
|
|
145
|
+
console.log(JSON.stringify({ target: opts.target, plan: result, text }, null, 2));
|
|
146
|
+
} else {
|
|
147
|
+
console.log(text);
|
|
148
|
+
}
|
|
149
|
+
process.exit(result.ok ? 0 : 1);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function readBundle(positional) {
|
|
153
|
+
return resolveJobForgeContextBundle(readBundleName(positional), PROJECT_DIR);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function readBundleName(positional) {
|
|
157
|
+
const bundleName = positional[0];
|
|
158
|
+
if (!bundleName) throw new Error('missing bundle name');
|
|
159
|
+
return bundleName;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function planOptions(opts, includeContent) {
|
|
163
|
+
return {
|
|
164
|
+
root: opts.root || PROJECT_DIR,
|
|
165
|
+
includeContent,
|
|
166
|
+
tokenBudget: opts.tokenBudget,
|
|
167
|
+
charsPerToken: opts.charsPerToken,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function parseTarget(value) {
|
|
172
|
+
if (value === 'markdown' || value === 'json') return value;
|
|
173
|
+
throw new Error('--target must be markdown or json');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function parsePositiveInteger(value, flag) {
|
|
177
|
+
const number = Number(value);
|
|
178
|
+
if (!Number.isInteger(number) || number <= 0) throw new Error(`${flag} must be a positive integer`);
|
|
179
|
+
return number;
|
|
180
|
+
}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
{
|
|
2
|
+
"defaults": {
|
|
3
|
+
"tokenBudget": 12000,
|
|
4
|
+
"charsPerToken": 4
|
|
5
|
+
},
|
|
6
|
+
"bundles": [
|
|
7
|
+
{
|
|
8
|
+
"name": "base",
|
|
9
|
+
"description": "Shared JobForge orchestration contract.",
|
|
10
|
+
"tokenBudget": 4000,
|
|
11
|
+
"files": [
|
|
12
|
+
{
|
|
13
|
+
"path": "AGENTS.harness.md",
|
|
14
|
+
"maxTokens": 3500,
|
|
15
|
+
"required": false,
|
|
16
|
+
"notes": [
|
|
17
|
+
"Consumer-project symlink to the shared harness contract."
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"path": "iso/instructions.md",
|
|
22
|
+
"maxTokens": 3500,
|
|
23
|
+
"required": false,
|
|
24
|
+
"notes": [
|
|
25
|
+
"Harness-source fallback; mode/reference files should be selected through narrower bundles."
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "shared",
|
|
32
|
+
"extends": "base",
|
|
33
|
+
"description": "Shared scoring model plus JobForge orchestration contract.",
|
|
34
|
+
"tokenBudget": 8000,
|
|
35
|
+
"files": [
|
|
36
|
+
{
|
|
37
|
+
"path": "modes/_shared.md",
|
|
38
|
+
"maxTokens": 4500,
|
|
39
|
+
"notes": [
|
|
40
|
+
"Loaded for evaluation-style modes that need archetypes, scoring, and profile references."
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"name": "auto-pipeline",
|
|
47
|
+
"extends": "shared",
|
|
48
|
+
"description": "Default JD/URL pipeline context.",
|
|
49
|
+
"tokenBudget": 12000,
|
|
50
|
+
"files": [
|
|
51
|
+
{
|
|
52
|
+
"path": "modes/auto-pipeline.md",
|
|
53
|
+
"maxTokens": 2000
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"path": "modes/reference-setup.md",
|
|
57
|
+
"maxTokens": 2600,
|
|
58
|
+
"required": false,
|
|
59
|
+
"notes": [
|
|
60
|
+
"Load when onboarding, tracker layout, or setup rules are the blocker."
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"name": "offer",
|
|
67
|
+
"extends": "shared",
|
|
68
|
+
"description": "Single-offer evaluation context.",
|
|
69
|
+
"tokenBudget": 11000,
|
|
70
|
+
"files": [
|
|
71
|
+
{
|
|
72
|
+
"path": "modes/offer.md",
|
|
73
|
+
"maxTokens": 2400
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"path": "modes/_shared-calibration.md",
|
|
77
|
+
"maxTokens": 2500,
|
|
78
|
+
"required": false,
|
|
79
|
+
"notes": [
|
|
80
|
+
"Load when score calibration or anchor examples are needed."
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"name": "compare",
|
|
87
|
+
"extends": "shared",
|
|
88
|
+
"description": "Offer comparison context.",
|
|
89
|
+
"tokenBudget": 8500,
|
|
90
|
+
"files": [
|
|
91
|
+
{
|
|
92
|
+
"path": "modes/compare.md",
|
|
93
|
+
"maxTokens": 600
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"name": "contact",
|
|
99
|
+
"extends": "shared",
|
|
100
|
+
"description": "LinkedIn outreach context.",
|
|
101
|
+
"tokenBudget": 9000,
|
|
102
|
+
"files": [
|
|
103
|
+
{
|
|
104
|
+
"path": "modes/contact.md",
|
|
105
|
+
"maxTokens": 1200
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"name": "pdf",
|
|
111
|
+
"extends": "shared",
|
|
112
|
+
"description": "CV/PDF generation context.",
|
|
113
|
+
"tokenBudget": 10000,
|
|
114
|
+
"files": [
|
|
115
|
+
{
|
|
116
|
+
"path": "modes/pdf.md",
|
|
117
|
+
"maxTokens": 2200
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"name": "apply",
|
|
123
|
+
"extends": "shared",
|
|
124
|
+
"description": "Application form-fill context with Geometra recovery rules.",
|
|
125
|
+
"tokenBudget": 23000,
|
|
126
|
+
"files": [
|
|
127
|
+
{
|
|
128
|
+
"path": "modes/apply.md",
|
|
129
|
+
"maxTokens": 7800
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"path": "modes/reference-geometra.md",
|
|
133
|
+
"maxTokens": 5600
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"path": "modes/reference-portals.md",
|
|
137
|
+
"maxTokens": 2500,
|
|
138
|
+
"required": false,
|
|
139
|
+
"notes": [
|
|
140
|
+
"Load when OTP, proxy, or portal configuration is the blocker."
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"name": "pipeline",
|
|
147
|
+
"extends": "shared",
|
|
148
|
+
"description": "Pending URL inbox context.",
|
|
149
|
+
"tokenBudget": 12000,
|
|
150
|
+
"files": [
|
|
151
|
+
{
|
|
152
|
+
"path": "modes/pipeline.md",
|
|
153
|
+
"maxTokens": 1500
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"path": "modes/reference-setup.md",
|
|
157
|
+
"maxTokens": 2600,
|
|
158
|
+
"required": false
|
|
159
|
+
}
|
|
160
|
+
]
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"name": "scan",
|
|
164
|
+
"extends": "shared",
|
|
165
|
+
"description": "Portal scanning context.",
|
|
166
|
+
"tokenBudget": 18000,
|
|
167
|
+
"files": [
|
|
168
|
+
{
|
|
169
|
+
"path": "modes/scan.md",
|
|
170
|
+
"maxTokens": 6500
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"path": "modes/reference-portals.md",
|
|
174
|
+
"maxTokens": 2500
|
|
175
|
+
}
|
|
176
|
+
]
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"name": "batch",
|
|
180
|
+
"extends": "shared",
|
|
181
|
+
"description": "Batch processing and durable runner context.",
|
|
182
|
+
"tokenBudget": 16000,
|
|
183
|
+
"files": [
|
|
184
|
+
{
|
|
185
|
+
"path": "modes/batch.md",
|
|
186
|
+
"maxTokens": 1500
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"path": "batch/batch-prompt.md",
|
|
190
|
+
"maxTokens": 4800,
|
|
191
|
+
"required": false,
|
|
192
|
+
"notes": [
|
|
193
|
+
"Needed when invoking or auditing the standalone batch runner prompt."
|
|
194
|
+
]
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"path": "modes/reference-setup.md",
|
|
198
|
+
"maxTokens": 2600,
|
|
199
|
+
"required": false
|
|
200
|
+
}
|
|
201
|
+
]
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"name": "tracker",
|
|
205
|
+
"extends": "base",
|
|
206
|
+
"description": "Tracker/status context with setup reference.",
|
|
207
|
+
"tokenBudget": 7000,
|
|
208
|
+
"files": [
|
|
209
|
+
{
|
|
210
|
+
"path": "modes/tracker.md",
|
|
211
|
+
"maxTokens": 500
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"path": "modes/reference-setup.md",
|
|
215
|
+
"maxTokens": 2600
|
|
216
|
+
}
|
|
217
|
+
]
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"name": "deep",
|
|
221
|
+
"extends": "base",
|
|
222
|
+
"description": "Company research context.",
|
|
223
|
+
"tokenBudget": 5500,
|
|
224
|
+
"files": [
|
|
225
|
+
{
|
|
226
|
+
"path": "modes/deep.md",
|
|
227
|
+
"maxTokens": 1200
|
|
228
|
+
}
|
|
229
|
+
]
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"name": "training",
|
|
233
|
+
"extends": "base",
|
|
234
|
+
"description": "Course/certification evaluation context.",
|
|
235
|
+
"tokenBudget": 4500,
|
|
236
|
+
"files": [
|
|
237
|
+
{
|
|
238
|
+
"path": "modes/training.md",
|
|
239
|
+
"maxTokens": 400
|
|
240
|
+
}
|
|
241
|
+
]
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"name": "project",
|
|
245
|
+
"extends": "base",
|
|
246
|
+
"description": "Portfolio project evaluation context.",
|
|
247
|
+
"tokenBudget": 4500,
|
|
248
|
+
"files": [
|
|
249
|
+
{
|
|
250
|
+
"path": "modes/project.md",
|
|
251
|
+
"maxTokens": 400
|
|
252
|
+
}
|
|
253
|
+
]
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
"name": "followup",
|
|
257
|
+
"extends": "base",
|
|
258
|
+
"description": "Follow-up triage context.",
|
|
259
|
+
"tokenBudget": 5500,
|
|
260
|
+
"files": [
|
|
261
|
+
{
|
|
262
|
+
"path": "modes/followup.md",
|
|
263
|
+
"maxTokens": 1000
|
|
264
|
+
}
|
|
265
|
+
]
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
"name": "rejection",
|
|
269
|
+
"extends": "base",
|
|
270
|
+
"description": "Rejection logging and pattern review context.",
|
|
271
|
+
"tokenBudget": 5500,
|
|
272
|
+
"files": [
|
|
273
|
+
{
|
|
274
|
+
"path": "modes/rejection.md",
|
|
275
|
+
"maxTokens": 1100
|
|
276
|
+
}
|
|
277
|
+
]
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
"name": "negotiation",
|
|
281
|
+
"extends": "base",
|
|
282
|
+
"description": "Offer negotiation context.",
|
|
283
|
+
"tokenBudget": 6500,
|
|
284
|
+
"files": [
|
|
285
|
+
{
|
|
286
|
+
"path": "modes/negotiation.md",
|
|
287
|
+
"maxTokens": 1600
|
|
288
|
+
}
|
|
289
|
+
]
|
|
290
|
+
}
|
|
291
|
+
]
|
|
292
|
+
}
|