job-application-agent 3.1.0 → 3.1.2

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/README.md CHANGED
@@ -2,201 +2,161 @@
2
2
 
3
3
  # 💼 Job Application Agent
4
4
 
5
- ### A privacy-first Agent Skill for a more disciplined job search
5
+ ### Find better roles, apply with verified facts, and learn from outcomes.
6
6
 
7
7
  [![Validate](https://github.com/vaibhavarora14/job-application-agent/actions/workflows/validate.yml/badge.svg)](https://github.com/vaibhavarora14/job-application-agent/actions/workflows/validate.yml)
8
- [![MIT License](https://img.shields.io/badge/license-MIT-2563EB.svg)](LICENSE)
9
- [![Agent Skill](https://img.shields.io/badge/Agent_Skills-compatible-111827)](job-application-agent/SKILL.md)
10
- [![Node 20+](https://img.shields.io/badge/Node.js-20%2B-339933?logo=nodedotjs&logoColor=white)](https://nodejs.org/)
11
8
  [![npm](https://img.shields.io/npm/v/job-application-agent?logo=npm&color=CB3837)](https://www.npmjs.com/package/job-application-agent)
9
+ [![MIT License](https://img.shields.io/badge/license-MIT-2563EB.svg)](LICENSE)
10
+ [![Agent Skills](https://img.shields.io/badge/Agent_Skills-compatible-111827)](job-application-agent/SKILL.md)
12
11
 
13
- **Discover better roles · Apply with verified facts · Keep private data local · Learn from outcomes**
14
-
15
- [Quick start](#-quick-start) · [How it works](#-how-it-works) · [Safety](#-safety-by-design) · [Privacy](#-privacy-model) · [Public dashboard](https://job-application-agent-telemetry.varora1406.workers.dev/) · [Analytics](#-usage-analytics) · [Security](SECURITY.md)
12
+ [Get started](#-get-started) · [Safety](#-safety) · [Privacy](#-privacy) · [Dashboard](https://job-application-agent-telemetry.varora1406.workers.dev/) · [Security](SECURITY.md)
16
13
 
17
14
  </div>
18
15
 
19
16
  ---
20
17
 
21
- Job Application Agent helps you discover, qualify, complete, and track your own job applications from any Agent Skills-compatible coding agent—without inventing credentials or hiding consequential decisions. It combines browser-assisted form filling with a verified résumé, candidate-defined targeting, secure local profile storage, duplicate detection, and an application ledger.
18
+ Job Application Agent is an [Agent Skill](https://agentskills.io/specification) that helps a coding agent discover, evaluate, complete, and track your own job applications. It uses one verified résumé, checks eligibility and duplicates, and records only confirmed submissions.
22
19
 
23
- ## Install for humans and agents
20
+ ## 🚀 Get started
24
21
 
25
- Run this one canonical command in a terminal:
22
+ Install it:
26
23
 
27
24
  ```bash
28
25
  npx job-application-agent@latest install
29
26
  ```
30
27
 
31
- If you are asking a coding agent to set it up, paste this:
28
+ Then tell your coding agent:
32
29
 
33
30
  ```text
34
- Install the Job Application Agent by running:
35
- npx job-application-agent@latest install
36
-
37
- Then confirm the installed version with:
38
- npx job-application-agent@latest status
31
+ Use job-application-agent to onboard my résumé and job preferences.
39
32
  ```
40
33
 
41
- Requires Node.js 20 or newer. The installer places the skill at `~/.agents/skills/job-application-agent` and enables automatic updates by default. Compatible agents load that vendor-neutral path; if a vendor skills directory such as `~/.cursor/skills` already exists, the installer also copies the skill there. The updater checks npm at login, every hour on macOS, Linux, and Windows, and at the start of a job-application workflow. Candidate profile data, the canonical résumé, telemetry identity, and application ledgers remain outside the replaceable skill directory.
42
-
43
- ```bash
44
- # See the installed version and update mode
45
- npx job-application-agent@latest status
34
+ After onboarding, use natural commands:
46
35
 
47
- # Update immediately
48
- npx job-application-agent@latest update
49
-
50
- # Explicitly opt out or back in
51
- npx job-application-agent@latest updates disable
52
- npx job-application-agent@latest updates enable
36
+ ```text
37
+ search jobs
38
+ list discovery sources for India and global remote engineering
39
+ apply https://company.example/jobs/123
40
+ apply all relevant jobs from this thread: <URL>
41
+ run a round of 10
42
+ show attention queue
43
+ record outcome Company — Senior Engineer — interview
53
44
  ```
54
45
 
55
- Updates are staged and validated before replacement. The immediately previous skill version is retained locally so a failed installation leaves the working version intact.
56
-
57
- > [!IMPORTANT]
58
- > You stay in control. The agent pauses for authentication, CAPTCHA, legal attestations, demographic questions, unclear eligibility, sensitive identifiers, and unverifiable claims.
46
+ Requires Node.js 20 or newer and a browser-capable coding agent.
59
47
 
60
48
  ## ✨ What it does
61
49
 
62
- | 🔎 Discover | 🎯 Qualify | 📝 Apply |
63
- |---|---|---|
64
- | Finds active roles on direct career pages and major ATS platforms. | Scores seniority, skills, location, eligibility, work mode, and compensation. | Fills forms using only verified profile and résumé facts. |
65
- | Resolves social and aggregator leads to direct employer pages. | Skips closed, duplicated, ineligible, and weak-fit opportunities. | Uploads one canonical résumé directly by path when the browser supports it, and drafts truthful short answers. |
66
-
67
- | 🔐 Protect | 📚 Track | 📈 Improve |
68
- |---|---|---|
69
- | Keeps profile data in OS-backed storage and browser auth in the browser. | Records only visibly confirmed submissions in a private local ledger. | Reviews results every ten applications and proposes targeting changes. |
70
- | Stops at sensitive or judgment-heavy steps. | Captures explicit round IDs and a resumable attention queue. | Opens tested, sanitized improvement PRs without merging or publishing them. |
71
-
72
- ## 🛡️ Safety by design
73
-
74
- The skill deliberately pauses for decisions or actions that should stay with you:
75
-
76
- - passwords, SSO, MFA, and CAPTCHA;
77
- - demographic and voluntary self-identification questions;
78
- - legal attestations and government identifiers;
79
- - unclear work authorization, sponsorship, location, or compensation;
80
- - claims that cannot be verified from your profile or résumé.
81
-
82
- It never reads browser cookies or session files, and it records an application as submitted only after the destination shows a clear success confirmation.
83
-
84
- ## 🚀 Quick start
85
-
86
- ### 1. Install the skill
87
-
88
- ```sh
89
- npx job-application-agent@latest install
90
- ```
50
+ | Stage | Behavior |
51
+ |---|---|
52
+ | **Discover** | Searches a shared, versioned catalog of direct careers, ATS platforms, networks, feeds, and job boards, then verifies every lead at the employer. |
53
+ | **Qualify** | Checks seniority, skills, location, authorization, compensation, and posting status. |
54
+ | **Apply** | Fills forms and uploads one canonical résumé using verified facts only. |
55
+ | **Track** | Deduplicates applications and records only visible submission confirmations. |
56
+ | **Improve** | Reviews outcomes and proposes targeting changes without rewriting candidate facts. |
91
57
 
92
- This is the supported installation path for both people and coding agents. After install, ask the current agent to list available skills if it does not pick up `job-application-agent` immediately.
58
+ ## 🤖 Choose your autonomy level
93
59
 
94
- ### 2. Onboard your profile
60
+ - **`review-each`** review every completed application before submission.
61
+ - **`routine-auto`** — allow routine submissions while keeping sensitive and judgment-heavy steps with you.
95
62
 
96
- Start a new agent chat and invoke this skill however your agent names skills (`$job-application-agent`, `/job-application-agent`, or natural language):
63
+ For durable autonomy across resumable or scheduled runs:
97
64
 
98
- ```text
99
- Use job-application-agent to onboard my resume and job-search preferences.
65
+ ```bash
66
+ echo '{"mode":"routine-auto"}' | node ~/.agents/skills/job-application-agent/scripts/job-application.mjs autonomy grant --stdin
100
67
  ```
101
68
 
102
- The agent will ask for your canonical résumé and missing application facts. You choose one of two submission modes:
103
-
104
- - `review-each` — inspect every completed application before submission.
105
- - `routine-auto` — allow routine submissions within a destination or batch you explicitly authorize; safety pauses still apply.
106
-
107
- For continuing autonomy across resumable and scheduled runs, explicitly grant the fixed routine scope once:
69
+ Check or revoke it at any time:
108
70
 
109
- ```sh
110
- echo '{"mode":"routine-auto"}' | node ~/.agents/skills/job-application-agent/scripts/job-application.mjs autonomy grant --stdin
71
+ ```bash
111
72
  node ~/.agents/skills/job-application-agent/scripts/job-application.mjs autonomy status
73
+ node ~/.agents/skills/job-application-agent/scripts/job-application.mjs autonomy revoke
112
74
  ```
113
75
 
114
- The grant covers routine discovery, filling, canonical résumé upload, submission, verified recruiting email, ledger/outcome updates, completed-tab cleanup, and sanitized improvement-PR creation. It never bypasses login, MFA, CAPTCHA, legal/demographic steps, host permission prompts, or ambiguous facts. `autonomy revoke` stops future routine transmissions without deleting history.
76
+ ## 🛡️ Safety
115
77
 
116
- ### 3. Use natural commands
78
+ The agent pauses for:
117
79
 
118
- ```text
119
- search jobs
120
- apply https://company.example/jobs/123
121
- apply all relevant jobs from this thread: <URL>
122
- run a round of 10
123
- show attention queue
124
- record outcome Company — Senior Engineer — interview
125
- ```
80
+ - passwords, SSO, MFA, and CAPTCHA;
81
+ - legal attestations and government identifiers;
82
+ - demographic or voluntary self-identification questions;
83
+ - unclear work authorization, sponsorship, location, or compensation;
84
+ - claims that cannot be verified from your profile or résumé;
85
+ - browser or operating-system permission prompts.
86
+
87
+ It never reads browser cookies or session files, bypasses access controls, or counts a filled form as a submission.
126
88
 
127
89
  ## 🧭 How it works
128
90
 
129
91
  ```mermaid
130
92
  flowchart LR
131
- A["Verified résumé + profile"] --> B["Discover direct roles"]
132
- B --> C["Validate activity and eligibility"]
133
- C --> D["Score and deduplicate"]
134
- D --> E["Fill truthful application"]
135
- E --> F{"Manual action needed?"}
136
- F -- Yes --> G["Pause for candidate"]
137
- F -- No --> H["Validate and submit"]
138
- G --> H
139
- H --> I["Confirm success and update ledger"]
93
+ A["Verified résumé + profile"] --> B["Find active roles"]
94
+ B --> C["Check fit + duplicates"]
95
+ C --> D["Fill truthful application"]
96
+ D --> E{"Needs you?"}
97
+ E -- Yes --> F["Attention queue"]
98
+ E -- No --> G["Submit"]
99
+ F --> G
100
+ G --> H["Confirm + record"]
140
101
  ```
141
102
 
142
- The bundled script provides deterministic profile validation, résumé import, scoring, company/requisition deduplication, explicit round accounting, attention/friction queues, ledger updates, and ten-application reviews. The current coding agent handles discovery and browser interaction while following the guardrails in [`SKILL.md`](job-application-agent/SKILL.md).
143
-
144
- ## 🔐 Privacy model
103
+ The bundled CLI handles private profile storage, résumé import, scoring, duplicate checks, resumable rounds, attention queues, and application/outcome ledgers. The coding agent handles discovery and browser interaction under the rules in [`SKILL.md`](job-application-agent/SKILL.md).
145
104
 
146
- | Data | Storage | Repository |
147
- |---|---|---|
148
- | Candidate profile | OS-backed secret store (macOS Keychain, or Windows Credential Manager + DPAPI) | Never committed |
149
- | Canonical résumé | Owner-only local state directory | Never committed |
150
- | Application ledger | Owner-only local state directory | Never committed |
151
- | Autonomy, round, attention, and friction state | Owner-only local state directory | Never committed |
152
- | Browser authentication | Existing browser session | Never exported |
153
- | Skill instructions and scripts | Local skill directory | Version controlled |
105
+ Discovery combines the reviewed [`SOURCES.json`](job-application-agent/references/SOURCES.json) catalog with an anonymous community registry. Repeatable public boards and feeds found by users or agents are sanitized and shared by default through `sources suggest --stdin`; disable this independently with `sources sharing disable`. Each contribution enters a private pending moderation queue. Only a maintainer-reviewed source becomes publicly searchable. One-off jobs, personal profiles, referral parameters, and candidate data are never published as sources, and every lead must still resolve to a direct employer or ATS before use.
154
106
 
155
- The package contains no candidate profile, résumé, application history, credentials, or browser data. The included [`.gitignore`](.gitignore) adds a second line of defense against committing common private artifacts.
107
+ ## 🔐 Privacy
156
108
 
157
- ## 📊 Usage analytics
109
+ | Data | Where it stays |
110
+ |---|---|
111
+ | Profile | macOS Keychain or Windows Credential Manager |
112
+ | Résumé and ledgers | Owner-only local state directory |
113
+ | Browser login | Existing browser session |
114
+ | Source-sharing preference | Owner-only local state directory |
115
+ | Skill code | Version-controlled installation directory |
158
116
 
159
- Structured anonymous usage analytics are enabled by default so the project can learn which discovery sources, job segments, ATS platforms, and application steps work well. Analytics may include company, role title, job domain/hash, published salary band, fit score, workflow stages, pauses, submissions, outcomes, and bounded interview-quality/failure-point categories. Local reviews also correlate interview quality with source and fit-score bands; private notes never enter analytics.
117
+ Candidate data, résumés, application history, credentials, and browser sessions are never committed to this repository.
160
118
 
161
- It never includes candidate identity, profile fields, résumé content, prompts, form answers, notes, browser data, IP addresses, or raw errors. A Cloudflare relay validates the schema before forwarding personless events to a private PostHog dashboard.
119
+ Anonymous structured analytics are enabled by default to improve the agent. They may include job and workflow categories, but never candidate identity, résumé content, prompts, answers, browser data, IP addresses, or raw errors.
162
120
 
163
- The [public usage dashboard](https://job-application-agent-telemetry.varora1406.workers.dev/) shows aggregate installations, activity, applications, outcomes, ATS mix, and role seniority. The relay increments a separate aggregate-only Cloudflare D1 store after PostHog accepts each event. The public API exposes no raw events or installation identifiers and suppresses small segments.
121
+ Anonymous community source sharing is also enabled by default, separately from analytics. It shares only sanitized metadata for repeatable public job-discovery surfaces. The registry stores no raw installation IDs; source-scoped contributor hashes and counts are used only for deduplication and moderation prioritization, never as identity or publication authority.
164
122
 
165
- ```sh
123
+ ```bash
166
124
  node ~/.agents/skills/job-application-agent/scripts/job-application.mjs telemetry status
167
125
  node ~/.agents/skills/job-application-agent/scripts/job-application.mjs telemetry disable
126
+ node ~/.agents/skills/job-application-agent/scripts/job-application.mjs sources sharing status
127
+ node ~/.agents/skills/job-application-agent/scripts/job-application.mjs sources sharing disable
168
128
  ```
169
129
 
170
- See the complete event contract, retention policy, and controls in [`ANALYTICS.md`](job-application-agent/references/ANALYTICS.md).
171
-
172
- ## 🧰 Requirements
130
+ See [`ANALYTICS.md`](job-application-agent/references/ANALYTICS.md) for the event contract and retention policy, or view the [public aggregate dashboard](https://job-application-agent-telemetry.varora1406.workers.dev/).
173
131
 
174
- - Node.js 20 or newer
175
- - A browser-capable coding agent that loads [Agent Skills](https://agentskills.io/specification)
176
- - OS-backed profile storage (macOS Keychain, or Windows Credential Manager + DPAPI)
132
+ <details>
133
+ <summary><strong>Installation and update details</strong></summary>
177
134
 
178
- Secure profile storage is supported on macOS and Windows. Linux can keep ledgers and a canonical résumé locally, but profile storage needs macOS or Windows.
135
+ The installer places the skill at `~/.agents/skills/job-application-agent` and enables automatic updates by default. Compatible vendor skill directories are also supported when they already exist.
179
136
 
180
- ## ✅ Validate locally
181
-
182
- ```sh
183
- npm test
137
+ ```bash
138
+ npx job-application-agent@latest status
139
+ npx job-application-agent@latest update
140
+ npx job-application-agent@latest updates disable
141
+ npx job-application-agent@latest updates enable
184
142
  ```
185
143
 
186
- GitHub Actions validates the skill frontmatter and runs the same test suite on every push and pull request.
144
+ Updates are staged and validated before replacement. Private candidate state lives outside the replaceable skill directory.
187
145
 
188
- ## 💬 Use without installation
146
+ </details>
189
147
 
190
- Paste [`SHARE_PROMPT.md`](SHARE_PROMPT.md) into a new agent chat. The installed skill is recommended for repeat use because it bundles deterministic checks and private local state handling.
148
+ ## 🧰 Develop
191
149
 
192
- ## ⚖️ Responsible use
150
+ ```bash
151
+ npm test
152
+ ```
193
153
 
194
- This project assists a person with their own job search. It does not guarantee interviews, offers, eligibility, or application accuracy. You are responsible for reviewing factual claims, complying with applicable laws and platform terms, and deciding when an application should be submitted. Do not use it to impersonate another person, evade access controls, bypass CAPTCHA, or make deceptive claims.
154
+ GitHub Actions validates the skill and runs the same test suite on every pull request. See [`CONTRIBUTING.md`](CONTRIBUTING.md) for the full local verification and review contract. To try the workflow without installing, paste [`SHARE_PROMPT.md`](SHARE_PROMPT.md) into a new agent chat.
195
155
 
196
- ## 🛡️ Security
156
+ ## ⚖️ Responsible use
197
157
 
198
- Please report suspected privacy or security issues using the private process in [`SECURITY.md`](SECURITY.md). Do not open a public issue containing personal data, credentials, résumé content, or application records.
158
+ Use this project only for your own job search. It does not guarantee interviews, offers, eligibility, or application accuracy. Never use it to impersonate another person, bypass CAPTCHA, evade access controls, or make deceptive claims.
199
159
 
200
- ## 📄 License
160
+ Report privacy or security issues through the process in [`SECURITY.md`](SECURITY.md). Do not open a public issue containing personal data or application records.
201
161
 
202
162
  Released under the [MIT License](LICENSE).
@@ -24,24 +24,27 @@ Use `scripts/job-application.mjs` for private state and deterministic checks. Re
24
24
  5. Use `review-each` for per-application approval. Use `routine-auto` only when the current request authorizes the destination or batch and every automatic-eligibility condition passes.
25
25
  6. When the candidate explicitly grants continuing autonomy, read [references/AUTONOMY.md](references/AUTONOMY.md) and persist it with `autonomy grant --stdin`. Do not repeat skill-level upload or submission approval prompts while the active grant and profile both use `routine-auto`.
26
26
  7. Obey browser and tool confirmation requirements regardless of the stored mode or autonomy grant.
27
- 8. Disclose default-enabled structured anonymous analytics and the `telemetry disable` control. The CLI also displays this disclosure.
27
+ 8. Disclose default-enabled structured anonymous analytics and the `telemetry disable` control. Disclose default-enabled anonymous community source sharing and the independent `sources sharing disable` control. The CLI also displays these disclosures before the first eligible transmission.
28
28
 
29
29
  Never store passwords, MFA codes, government IDs, demographic data, CAPTCHA answers, browser session data, or inferred candidate facts.
30
30
 
31
31
  ## Discover and assess
32
32
 
33
- 1. Resolve discovery leads to the direct employer or ATS page.
34
- 2. Verify the application channel immediately before assessment. Mark it `active`, `closed`, or `unclear`.
35
- 3. Classify eligibility only after checking residence, location, work authorization, sponsorship, schedule, and employment type.
36
- 4. Extract explicit seniority, experience range, work mode, locations, comparable published salary maximum, and all must-have requirements.
37
- 5. Classify each must-have as `met`, `partial`, `missing`, or `unclear`. Attach private, resume-backed evidence for `met` and `partial`; never invent evidence.
38
- 6. Run `score --stdin`. Apply the returned gate decision before considering the score:
33
+ Read [references/SOURCES.md](references/SOURCES.md) before the first discovery pass in a workflow.
34
+
35
+ 1. Run `sources list` (optionally filtered) and search the highest-signal packaged and maintainer-reviewed community sources. Resolve every lead to the direct employer or ATS page.
36
+ 2. Attribute the lead with coarse `discoverySource`, stable packaged-catalog `discoverySourceId` when known, and independent `applicationChannel`. Treat a one-off user link as `user-supplied`. Whenever a user or agent discovers a repeatable public board, feed, directory, or careers index that is not already listed, run `sources suggest --stdin`; the CLI contributes its sanitized metadata by default unless community sharing has been disabled.
37
+ 3. Verify the application channel immediately before assessment. Mark it `active`, `closed`, or `unclear`.
38
+ 4. Classify eligibility only after checking residence, location, work authorization, sponsorship, schedule, and employment type.
39
+ 5. Extract explicit seniority, experience range, work mode, locations, comparable published salary maximum, and all must-have requirements.
40
+ 6. Classify each must-have as `met`, `partial`, `missing`, or `unclear`. Attach private, resume-backed evidence for `met` and `partial`; never invent evidence.
41
+ 7. Run `score --stdin`. Apply the returned gate decision before considering the score:
39
42
  - `exclude`: closed or stale channel, explicit ineligibility, excluded company/location, or incompatible work mode.
40
43
  - `ask`: unclear posting status, eligibility, authorization, location/work mode, seniority, or requirement evidence.
41
44
  - `skip`: explicit non-target seniority, comparable compensation below the configured floor, insufficient must-have coverage, or score below the manual-review floor.
42
45
  - `review`: a candidate for manual review or routine auto-submission.
43
- 7. Treat `autoEligible: true` as necessary but not sufficient to submit. It requires all gates to pass, exact Senior/Staff alignment, score at least 80, at least 70% evidenced must-have coverage, and no material experience-range mismatch.
44
- 8. Keep scores from 70 through 79 in manual review. Do not auto-submit when must-have analysis is absent or uncertain.
46
+ 8. Treat `autoEligible: true` as necessary but not sufficient to submit. It requires all gates to pass, exact Senior/Staff alignment, score at least 80, at least 70% evidenced must-have coverage, and no material experience-range mismatch.
47
+ 9. Keep scores from 70 through 79 in manual review. Do not auto-submit when must-have analysis is absent or uncertain.
45
48
 
46
49
  Do not lower seniority, compensation, location, work mode, or evidence thresholds to increase volume. Unknown compensation does not exclude a role; pause if the application asks the candidate to state or accept compensation.
47
50
 
@@ -51,16 +54,17 @@ For batches, scheduled work, or resumable handoffs, read [references/RUNS.md](re
51
54
 
52
55
  1. Recheck employer, title, direct domain, posting status, eligibility, and `autoEligible` immediately before submission.
53
56
  2. Run `ledger check --stdin` with the internal ledger ID, canonical URL, employer job ID, company, and role when available. Review both requisition duplicate status and same-company history.
54
- 3. Stop on a hard duplicate. Treat a same-company/same-role match without a shared job ID as a possible duplicate. Use `duplicateOverride: "NEW REQUISITION CONFIRMED"` only after verifying it is a distinct requisition.
55
- 4. Keep authentication in the existing browser session. Never inspect cookies, local storage, passwords, or session files.
56
- 5. Fill only explicit profile fields, candidate-provided answers, or facts verified in the canonical resume.
57
- 6. Follow [references/APPLICATION_GUIDANCE.md](references/APPLICATION_GUIDANCE.md) for narrative answers.
58
- 7. Upload only the canonical resume unless the candidate explicitly provides another attachment. Resolve its absolute path with `resume path`, then follow [references/BROWSER_UPLOADS.md](references/BROWSER_UPLOADS.md). Use the browser's privileged path-based upload capability first; treat a visible native file picker as a fallback.
59
- 8. Do not answer demographic questions. Stop for login/SSO/MFA, CAPTCHA, legal attestations, unclear authorization or compensation, sensitive identifiers, and judgment-only questions.
60
- 9. Verify every required field, answer, attachment, and disclosure. Submit when the current request or active autonomy grant authorizes it.
61
- 10. Record `submitted` only after visible success confirmation, using independent `discoverySource`, `applicationChannel`, and `roundId` values. Record no submission when confirmation is missing or ambiguous.
62
- 11. Record workflow telemetry with `telemetry record --stdin`. Let `ledger add` emit `application_submitted`; do not emit it twice. Pass job URLs and structured metrics only through documented transient fields.
63
- 12. Queue hard stops with `attention add --stdin` and continue elsewhere. Record reproducible general-purpose failures with `friction record --stdin`; improvement work must never delay application work.
57
+ 3. Stop on a hard ledger-ID, canonical-URL, employer-job-ID, or requisition duplicate. Treat a same-company/same-role alias as a possible duplicate. Use `duplicateOverride: "NEW REQUISITION CONFIRMED"` only after verifying it is a distinct requisition.
58
+ 4. For a genuinely different role at a previously applied company, follow `companyReapply`: proceed automatically only when it returns `eligible-after-cooldown` (15 full days since the latest company application and no recorded outcome). `cooldown-active` and `follow-up-present` require the candidate's explicit approval and `companyReapplyOverride: "CANDIDATE APPROVED EARLY REAPPLICATION"`.
59
+ 5. Keep authentication in the existing browser session. Never inspect cookies, local storage, passwords, or session files.
60
+ 6. Fill only explicit profile fields, candidate-provided answers, or facts verified in the canonical resume.
61
+ 7. Follow [references/APPLICATION_GUIDANCE.md](references/APPLICATION_GUIDANCE.md) for narrative answers.
62
+ 8. Upload only the canonical resume unless the candidate explicitly provides another attachment. Resolve its absolute path with `resume path`, then follow [references/BROWSER_UPLOADS.md](references/BROWSER_UPLOADS.md). Use the browser's privileged path-based upload capability first; treat a visible native file picker as a fallback.
63
+ 9. Do not answer demographic questions. Stop for login/SSO/MFA, CAPTCHA, legal attestations, unclear authorization or compensation, sensitive identifiers, and judgment-only questions.
64
+ 10. Verify every required field, answer, attachment, and disclosure. Submit when the current request or active autonomy grant authorizes it.
65
+ 11. Record `submitted` only after visible success confirmation, using independent `discoverySource`, `discoverySourceId`, `applicationChannel`, and `roundId` values. Record no submission when confirmation is missing or ambiguous.
66
+ 12. Record workflow telemetry with `telemetry record --stdin`. Let `ledger add` emit `application_submitted`; do not emit it twice. Pass job URLs and structured metrics only through documented transient fields.
67
+ 13. Queue hard stops with `attention add --stdin` and continue elsewhere. Record reproducible general-purpose failures with `friction record --stdin`; improvement work must never delay application work.
64
68
 
65
69
  ## Outcomes and reviews
66
70
 
@@ -93,6 +97,11 @@ node scripts/job-application.mjs autonomy grant --stdin
93
97
  node scripts/job-application.mjs autonomy status|preview|revoke
94
98
  node scripts/job-application.mjs round start|complete --stdin
95
99
  node scripts/job-application.mjs round status [round-id]
100
+ node scripts/job-application.mjs sources list [--stdin]
101
+ node scripts/job-application.mjs sources suggest --stdin
102
+ node scripts/job-application.mjs sources pending
103
+ node scripts/job-application.mjs sources sync
104
+ node scripts/job-application.mjs sources sharing status|enable|disable|reset
96
105
  node scripts/job-application.mjs attention add|resolve --stdin
97
106
  node scripts/job-application.mjs attention list
98
107
  node scripts/job-application.mjs friction record --stdin
@@ -25,12 +25,16 @@ node scripts/job-application.mjs telemetry record --stdin
25
25
 
26
26
  Telemetry is best effort. It has no offline queue, uses a short network timeout, and never changes the result of a job-application command.
27
27
 
28
+ Community source sharing is a separate default-enabled feature with independent `sources sharing status|enable|disable|reset` controls. It does not send analytics events or store a raw contributor identity with a source; a source-scoped HMAC is used only for unique-system counting. See [`SOURCES.md`](SOURCES.md) for its exact public metadata contract.
29
+
28
30
  ## Identity boundary
29
31
 
30
32
  Analytics never includes the candidate's name, email, phone, exact address, profile URLs, candidate location, work authorization, personal compensation or compensation floor, target profile or thresholds, resume or attachments, must-have evidence or coverage details, rejection reasons, prompts, responses, job descriptions, form questions, drafted answers, notes, passwords, MFA, CAPTCHA, legal or demographic answers, browser data, IP address, request headers, user agent, or raw error messages.
31
33
 
32
34
  Structured job context may include company, role title, canonical destination domain, a SHA-256 hash of the job URL after removing query parameters and fragments, bounded discovery source, ATS/application channel, job country, work mode, employment type, seniority, role family, published salary band, fit score, match/gap categories, workflow stages, field categories, pause reasons, submission result, outcome, bounded interview quality, and bounded interview failure point.
33
35
 
36
+ The more specific local `discoverySourceId` catalog attribution is not transmitted in v1.
37
+
34
38
  Local attention details and friction evidence are never transmitted. Analytics may receive only their already-documented bounded stage, ATS, pause reason, result, and aggregate count fields.
35
39
 
36
40
  Company and title values are bounded and rejected when they resemble an email, phone number, URL, LinkedIn profile, or GitHub profile.
@@ -14,13 +14,14 @@ Start input: `{ "requestedCount": 30 }`. Complete input: `{ "roundId": "round-..
14
14
 
15
15
  Count only unique applications with a visible employer/ATS confirmation or a verified sent recruiting email that were also added to the ledger with the same `roundId`. Filled forms, blockers, drafts, unsent email, and ambiguous confirmations never count. `round complete` rejects an under-target round.
16
16
 
17
- Run both company-level and requisition-level duplicate checks before filling and again immediately before transmission. A prior company application is a review signal, not by itself proof that a distinct requisition is a duplicate.
17
+ Run both company-level and requisition-level duplicate checks before filling and again immediately before transmission. Hard ledger-ID, canonical-URL, employer-job-ID, and requisition duplicates always stop. Same-role aliases require a verified distinct requisition and `NEW REQUISITION CONFIRMED`. A genuinely different role at the same company may proceed automatically only when `companyReapply.decision` is `eligible-after-cooldown`: 15 full days have passed since the latest company application and no outcome has been recorded. `cooldown-active` and `follow-up-present` require explicit candidate approval.
18
18
 
19
19
  Resolve the canonical résumé with `resume path`, upload its absolute path through the browser’s privileged chooser first, and verify the filename and parsed fields. Use a visible native picker only as a fallback.
20
20
 
21
21
  Store independent attribution on every new ledger row:
22
22
 
23
23
  - `discoverySource`: where the lead was found (`linkedin`, `x`, `yc`, `hacker-news`, `job-board`, `direct-company`, `email`, `user-supplied`, `web-search`, or `other`).
24
+ - `discoverySourceId`: stable packaged catalog ID such as `yc-work-at-a-startup` or `hacker-news-who-is-hiring`, when known.
24
25
  - `applicationChannel`: where it was submitted (`ashby`, `greenhouse`, `lever`, `workday`, `company`, `email`, and the other documented ATS values).
25
26
  - `source`: the legacy-compatible application channel.
26
27
 
@@ -49,6 +49,7 @@ Treat `mustHaves[].evidence` as private resume analysis. It is used locally and
49
49
  "description": "Posting text",
50
50
  "source": "greenhouse",
51
51
  "discoverySource": "linkedin",
52
+ "discoverySourceId": "linkedin-jobs-feed",
52
53
  "applicationChannel": "greenhouse",
53
54
  "url": "https://job-boards.greenhouse.io/example/jobs/123",
54
55
  "postingStatus": "active",
@@ -72,7 +73,7 @@ Treat `mustHaves[].evidence` as private resume analysis. It is used locally and
72
73
 
73
74
  Allowed sources: `linkedin`, `greenhouse`, `lever`, `ashby`, `workable`, `comeet`, `workday`, `rippling`, `smartrecruiters`, `google-form`, `company`, `email`, and `other`.
74
75
 
75
- `source` remains the backward-compatible application channel. New workflows should also supply `discoverySource` (`direct-company`, `linkedin`, `x`, `yc`, `hacker-news`, `job-board`, `email`, `user-supplied`, `web-search`, or `other`) and `applicationChannel` using the allowed `source` values.
76
+ `source` remains the backward-compatible application channel. New workflows should also supply `discoverySource` (`direct-company`, `linkedin`, `x`, `yc`, `hacker-news`, `job-board`, `email`, `user-supplied`, `web-search`, or `other`), the kebab-case `discoverySourceId` from [`SOURCES.json`](SOURCES.json) when known, and `applicationChannel` using the allowed `source` values.
76
77
 
77
78
  Allowed posting statuses: `active`, `closed`, `unclear`. Allowed eligibility: `eligible`, `unclear`, `ineligible`. Allowed seniority: `junior`, `mid`, `senior`, `staff`, `principal`, `lead`, `manager`, `director`, `founding`, `unspecified`. Allowed work modes: `remote`, `hybrid`, `onsite`, `unspecified`. Must-have statuses: `met`, `partial`, `missing`, `unclear`.
78
79
 
@@ -94,6 +95,8 @@ Include as many identifiers as are known.
94
95
 
95
96
  The check removes fragments and non-job query parameters while retaining recognized job or requisition identifiers. Matching ledger ID, canonical URL, or same-company employer job ID is a hard duplicate. Same company and role without a shared job ID is a possible duplicate.
96
97
 
98
+ `ledger check` also returns `companyReapply`. A genuinely different role is `eligible-after-cooldown` only when at least 15 full days have passed since the latest application to that company and no outcome has been recorded for that application. Hard duplicates are never eligible. Same-role matches, `cooldown-active`, and `follow-up-present` remain blocked at `ledger add` unless their exact documented override is present.
99
+
97
100
  ## Confirmed submission input
98
101
 
99
102
  Add only after visible success confirmation.
@@ -107,6 +110,7 @@ Add only after visible success confirmation.
107
110
  "employerJobId": "greenhouse:123",
108
111
  "source": "company",
109
112
  "discoverySource": "x",
113
+ "discoverySourceId": "x-hiring-feed",
110
114
  "applicationChannel": "company",
111
115
  "roundId": "round-2026-01-15-00000000-0000-4000-8000-000000000000",
112
116
  "score": 84,
@@ -114,6 +118,7 @@ Add only after visible success confirmation.
114
118
  "submittedAt": "2026-01-15T10:00:00.000Z",
115
119
  "approval": "STANDING AUTHORIZATION",
116
120
  "duplicateOverride": "NEW REQUISITION CONFIRMED",
121
+ "companyReapplyOverride": "CANDIDATE APPROVED EARLY REAPPLICATION",
117
122
  "answers": { "Resume": "Canonical resume.pdf" },
118
123
  "telemetry": {
119
124
  "durationBucket": "5-15m",
@@ -124,9 +129,9 @@ Add only after visible success confirmation.
124
129
  }
125
130
  ```
126
131
 
127
- Use `duplicateOverride` only for a verified distinct requisition after a possible-duplicate warning. It and `telemetry` are transient and are not written to the application ledger. Use approval `APPROVE SUBMIT` for per-application approval or `STANDING AUTHORIZATION` when the current request authorizes routine batch submission.
132
+ Use `duplicateOverride` only for a verified distinct requisition after a possible-duplicate warning. Use `companyReapplyOverride` only when the candidate explicitly approves a different-role reapplication during the cooldown or after a recorded outcome. Both override phrases and `telemetry` are transient. An accepted company reapplication override stores only `reapplicationApproval: "candidate-explicit"` in the private ledger. Use approval `APPROVE SUBMIT` for per-application approval or `STANDING AUTHORIZATION` when the current request authorizes routine batch submission.
128
133
 
129
- `discoverySource`, `applicationChannel`, and `roundId` are optional for backward compatibility and should be supplied for new resumable rounds. `ledger check` returns hard requisition/URL duplicate status plus bounded same-company history so a distinct role can be reviewed without conflating it with a duplicate.
134
+ `discoverySource`, `discoverySourceId`, `applicationChannel`, and `roundId` are optional for backward compatibility and should be supplied for new resumable rounds. `discoverySourceId` remains local and is not included in telemetry. `ledger check` returns hard duplicate status, bounded same-company history, and the same `companyReapply` decision enforced by `ledger add` while holding the application lock.
130
135
 
131
136
  ## Autonomy grant input
132
137