LinkedIn Early-Career Weekly
Use this skill when Liam wants the new persistent LinkedIn flow: early-career software engineering roles from the last week, deduped against the tracker, tailored with a fresh worker, then applied with a separate fresh worker.
This is intentionally not based on linkedin-apply-all.
Default Invocation
When this workflow is run from chat and persistent goal tools are available, create a pursuing goal before launching any monitor, stage runner, browser actor, or sub-agent, and keep it active for the whole drain (including across context compaction). In Codex, use goal mode with the shared completion condition below:
/goal Drain the LinkedIn early-career weekly per the shared Persistence Goal
Keep that goal active and close it only when the workflow reaches search saturation, a systemic blocker, or an explicit user stop. Do not launch additional workers merely to satisfy the goal; the one-worker rule still wins.
Persistence Goal (shared with the linkedin-early-career-weekly-claude variant)
Both variants pursue one identical persistence goal so either agent knows to keep going. Keep this completion-condition text byte-identical across both skills:
Every fresh last-week LinkedIn Entry-level software-engineer posting from the configured search is discovered, deduped against the tracker, and driven to a terminal state — submitted with confirmation evidence, recorded as a precise manual blocker, marked already-applied/duplicate, or archived with a reason — until search saturation (
search.stopRequestedwith asaturationReason) orrunPolicy.maxJobs, with the markdown tracker and visualizer cache reconciled. Submit high-confidence applications when the tailored resume is verified, all required answers are truthful/standing-answer covered, and no true blocker remains. Stop early only on a systemic browser/auth/rate-limit blocker or an explicit user stop. Honor the one-worker / one-browser-actor rule; never spawn extra workers just to satisfy the goal.
When Liam asks to run this workflow from chat, launch the monitor:
python3 skills/linkedin-early-career-weekly/scripts/run_monitored.py
Resume after interruption or context compaction with:
python3 skills/linkedin-early-career-weekly/scripts/run_monitored.py --resume
The default search is LinkedIn software engineer, United States, Entry level, posted in the last week:
https://www.linkedin.com/jobs/search/?keywords=software+engineer&geoId=103644278&location=United+States&f_TPR=r604800&f_E=2&origin=JOB_SEARCH_PAGE_SEARCH_BUTTON
Useful Flags
--resumepreserves/tmp/linkedin_early_career_weekly_state.json.--max-jobs Nstops after N durable posting outcomes; default0means keep going until search saturation or a systemic blocker.--max-stages Nruns only N worker stages, useful for testing.--model MODELoverrides the worker model. Default comes fromCODEX_LATEST_MODELorgpt-5.5. Use--model defaultto omit-mand use Codex config.--no-refreshskips the initial visualizer cache refresh.--dry-runprints worker commands/prompts without launching browser work.
Architecture
run_monitored.py
- refreshes visualizer cache unless --resume or --no-refresh
- builds/resumes /tmp/linkedin_early_career_weekly_state.json
- restarts run_stages.py while progress is possible
run_stages.py
- takes /tmp/linkedin_early_career_weekly_worker.lock
- refuses parallel worker/stage execution while that lock is active
- authorizes only its single child stage worker while holding the lock
- advances existing discovered items before discovering more
- preflights spawned-worker Chrome extension access before browser stages
- launches one fresh Codex worker for one stage
fresh Codex worker
- discover: uses Liam Chrome profile to capture and dedupe one LinkedIn posting
- tailor: reads resume-tailor instructions, renders/verifies resume, updates tracker
- apply: uses Liam Chrome profile, Chrome plugin first, Computer Use fallback
- never uses Playwright, Playwright CLI, Puppeteer, npx browser tooling, or public scraping fallbacks
Operating Card
Before each stage, re-read:
skills/linkedin-early-career-weekly/OPERATING_CARD.md
Application workers should also read:
skills/finish-app-script/OPERATING_CARD.md
They borrow the live-form submission guardrails only. They must not invoke the
finish-app-script queue or write /tmp/fa_script_run_state.json.
Workers must also read the shared application-answer context used by the other recruiting skills:
skills/linkedin-easy-apply-nodriver/references/application-defaults.md
Durability
State lives at:
/tmp/linkedin_early_career_weekly_state.json
Worker outputs live at:
/tmp/linkedin_early_career_weekly_outputs/
Manual application pickup notes live at:
application-trackers/manual-application-handoffs.txt
Full job descriptions should be saved under:
/tmp/linkedin_early_career_weekly_descriptions/
The state tracks visited/skipped LinkedIn job URLs, result index, scroll checkpoint, duplicate streak, and item stages. A fresh parent can resume from only the operating card plus the state file.
Low-Memory Browser Policy
This workflow runs on Liam's 16 GB RAM laptop and must keep Chrome light by default.
- Keep at most two workflow tabs open during normal operation: one LinkedIn search/checkpoint tab and one active job/application tab.
- Do not leave manual/review tabs open by default. Record the exact blocker,
URL, resume path, filled-field summary, next action, and any FRQ drafts in
application-trackers/manual-application-handoffs.txt, state, and the tracker, then close/finalize the application tab. - Keep a manual handoff tab only when the live page contains unrecoverable state that cannot be reconstructed from the recorded URL and answers. Even then, keep at most one handoff tab for the whole workflow and close older workflow handoff tabs after recording their state.
- Before opening a new application tab, clean up stale workflow tabs from prior submitted, archived, duplicate, or manually recorded items.
- Avoid broad DOM snapshots or full-page screenshots on heavy ATS pages unless needed for a blocker. Prefer narrow locators, visible text, and small targeted DOM reads.
Guardrails
- One workflow worker and one browser actor at a time.
- Do not run a second monitor or worker while
/tmp/linkedin_early_career_weekly_worker.lockbelongs to an active process. - Use Liam's Chrome profile for both LinkedIn discovery and applications:
profile
Liam, accountliamvanpj@gmail.com, directoryDefault. - Use only the Codex Chrome plugin and Codex Computer Use for browser work. Do
not use Playwright, Playwright CLI, Puppeteer,
npx playwright, local browser wrapper scripts, or public scraping fallbacks. - Keep browser work in agent-owned Chrome tabs/tab groups so Liam can use
Chrome at the same time. Do not claim, navigate, reload, or reuse Liam's
active/current tab unless resuming that exact row's prepared handoff tab.
Preflight this before navigating: if an agent-owned tab in the Codex tab group
cannot be created, stop as a systemic browser blocker instead of touching a
posting or marking it manual. Keep the low-memory policy above: one search
tab, one active work tab, no pile of handoff tabs.
Spawned
codex execworkers may not havetool_search;run_stages.pyinjects the absolute Chrome pluginbrowser-client.mjspath so they can use the Node REPL JavaScript tool directly. If a spawnedcodex execworker cannot accessagent.browsers.get("extension")even though the desktop parent session can, treat that as a child-session Chrome bridge limitation. Do not retry the full LinkedIn run; run browser stages only from a plugin-visible desktop thread until the child bridge is available. - Dedupe before every side effect.
- Do not invent jobs, tracker rows, resumes, confirmations, or application outcomes.
- Do not update Notion unless Liam explicitly asks.
- Do not commit or push unless Liam explicitly asks.
- Do not use
skills/linkedin-apply-allas the base or state source.