AI Summary
Purpose:
- Make Claude's September 9–10 candidate report reproducible by Codex and
other agents without reconstructing the conversation again.
Key points:
- User preference updated September 11: discovery first; do not repeat known
candidates as the main result. Report newly posted versus older first-seen leads separately; keep company-alias exclusions and truthful zero-new runs.
- Entry point:
skills/job-posting-status/SKILL.md, routed byAGENTS.md. - Daily local refresh at 09:00/15:00 KST: see
ai/workspace/job-posting-automation/index.md for the schedule and limits.
- Deliver Korean Markdown and HTML at
human/career/YYYY-MM-공고-후보.*. - Preserve a combined ranking with direct posting URLs and work locations.
- Current scores (1–5), changed by user request on 2026-09-10: role fit
35%, finance 25%, welfare/culture 20%, salary information 20%. Unverified axes use 3?, not invented facts.
- Keep requirement verification, actual hiring status, role-fit class, and
company score separate. A high score does not settle a hiring-status doubt.
- Existing September reference has 28 combined rows. That is a historical
fixture, not a required number of future candidates.
Relevant when:
- Finding more postings, refreshing candidates, merging rankings, or checking
whether an apparently open position is actually recruiting.
Do not read full document unless:
- Executing or validating one of these operations.
Linked documents:
Open Questions
- Claude did not define deterministic cutoffs for every 1–5 qualitative axis
or its approximate fit percentages. Preserve documented scores for unchanged evidence; new judgments require reasons, not a claim of exact replication.
- Current public API schemas, access, and hiring status need verification at
execution time. This workflow reconstruction is not a fresh market scan.
Details
Inputs and scope
Read ai/workspace/active-context.md, the summaries in ai/wiki/people/hyunwook.md, 2026-career-transition.md, and 2026-active-job-shortlist.md, then the current month's candidate report. Use linked career/project evidence only when a requirement needs it.
The September scope was Data Engineer / Data Platform / Data Infra / DBA, product companies, Seoul/Pangyo or remote, and experience bands covering the candidate's approximately five years. Recalculate tenure from the career timeline on later runs. A DE-only request narrows this scope. IC technical depth was preferred; identify SI/MSP, client-site work, consulting, management, pure analytics, and ML-centric roles explicitly rather than treating them as equivalent fits.
For new-only scans derive company aliases, reviewed postings, prior rejections, declines, and submitted applications from current records. Do not hardcode the September exclusion list forever. New-only results exclude already reviewed companies by default; the combined ranking retains earlier researched candidates. Deduplicate cross-postings by employer + role + location and preserve all known channel IDs. Different roles at the same employer are not automatically duplicates.
Discovery-first order (user correction, September 11)
Unless the user explicitly asks to recheck existing candidates, begin with the latest bounded public lists and filter reviewed/submitted/rejected/declined employers before reading new details. Match company aliases as well as IDs; Concentrix Service Korea is not new merely because the old record says Concentrix. Preserve prior reports and snapshots as the exclusion memory. Record both the exact channel datePosted (or Unknown) and first_seen_at. A first discovery or new cross-posting ID is not proof of a newly created role. Present recent registrations first, older newly discovered roles second, and existing-status changes only as supplemental results. If zero new qualifying roles are found, say zero and state coverage; never fill a quota with old names. The combined report still retains old candidates and ranks without representing them as fresh discoveries. Changing this workflow does not verify a scheduler is currently running or authorize changing its schedule.
Collect and verify
Search lanes observed in Claude's run:
| Channel | Historical working path / limit |
|---|---|
| Wanted | Public /api/v4/jobs lists, /api/v4/search, /api/v4/jobs/<id> detail, /company/<id> company facts. Tags observed: 655, 1025, 10231. |
| Jumpit | jumpit-api.saramin.co.kr/api/positions, category/keyword lists and jumpit.saramin.co.kr/position/<id> details. |
| Saramin | Domain search, company recruiting pages, zf_user/jobs/view?rec_idx=<id>; list pages sometimes returned only a JS shell. |
| JobKorea | Search pages plus Recruit/GI_Read/<id>; some detail bodies were images, so use the exact role's cross-posting or a browser. |
| Remember | Public search and posting detail; JS/access limits must be recorded. |
| Rallit / Programmers / RocketPunch | Secondary discovery; date-less Rallit pages and DNS/403 failures were observed in this run. |
Use keywords 데이터 엔지니어, Data Engineer, 데이터 플랫폼, Data Platform, 데이터 인프라, DBA, MySQL, Airflow, ETL, 데이터 파이프라인. Check that list filters actually affect results and paginate within a stated bound. These historical endpoints are starting points, not guaranteed current API contracts. Parallel tools may help; a particular subagent count is not part of the output.
For each candidate preserve: employer/legal entity, role, direct URL and channel ID, fetched-at date/time, work location (not just headquarters), remote conditions, experience range, employment type, deadline, main duties, required/preferred qualifications separately, brief decisive quotations, gaps, and source links.
Keep these independent:
- Detail-read status: verified body / body unavailable.
- Hiring status: open as observed / closed / Needs confirmation, with date.
An apply button or "채용 시 마감" alone does not establish current recruitment when the listing is undated or contradicted elsewhere. Check the employer's own careers page and another channel for the same role/entity. A 403 or absent cross-posting does not prove closure. Old IDs are a recheck signal, not dates. The historical assertion that Rallit never expires listings was not independently verified; do not repeat it as a universal platform policy.
The 2026-09-10 afternoon refresh found explicit closure for Rallit IDs 133, 989, 83 and 1656. Inspect the exact props.pageProps.position object in the page's __NEXT_DATA__, match its ID and use status.code (CLOSE / HIRING). Recommended jobs elsewhere in the document have independent statuses. Move closed postings out of the active ranking even when generic deadline text says "채용 시 마감".
Role evidence and scoring
Count missing required categories among (1) Kafka/streaming, (2) Spark/Flink, (3) formal DW/Data Mart modeling including dbt or cloud warehouse platforms, (4) cloud data lake/lakehouse. Two or more: stretch; one: partial; zero: core-fit. Preferred-only mentions do not count; alternatives such as batch OR streaming do not require both. Count categories, not every product name. Flag central duties separately when they imply a gap absent from the required section. Missing mandatory Java, Oracle, Aurora, MongoDB, or other skills remain explicit gaps even when this narrow four-category classifier says core-fit. An unread or nearly empty requirement section cannot establish a strong fit.
Use current verified strengths (Python/SQL/Go, batch pipelines, Airflow/Kubernetes, MySQL operations/tuning, data integrity and monitoring). Do not convert EC2 self-managed MySQL into RDS/Aurora experience, or batch CDC into production Kafka/Flink streaming. Recheck ownership and numbers in the wiki when using them.
The user requested lower fit weight and higher salary weight on 2026-09-10. The current calculation supersedes the original 40/25/20/15:
total = fit * 0.35 + finance * 0.25 + welfare_culture * 0.20 + salary_info * 0.20
Each axis is 1–5. An unknown axis is neutral 3?; the ? survives merging and rendering. Calculate with decimal arithmetic, display two decimals, sort descending, and use competition ranks for ties (1, 2, 3, 3, 5). Preserve existing row order within a tie. Round only for display. Explain each new score with sourced facts. Approximate fit percentages are subjective evidence coverage, not hiring odds; omit new percentages unless their calculation is documented.
- Finance: prefer filings/audits or official investor material, then attributed
company statements and reputable reporting. Preserve fiscal period, currency, entity, consolidated/separate scope, and profit versus revenue distinctions. Funding is not profit; missing finance is not financial health.
- Welfare/culture: distinguish advertised policies from employee reviews; record
review date/sample size and team-specific uncertainty. Joiners/leavers need a period and headcount context; do not fabricate a turnover rate.
- Salary information: keep offered role bands, company-wide averages, platform
tags, and parent-company figures separate. A company average is not an offer. Show amounts (or unpublished), scope, source links and check dates alongside scores. Explain conflicting sources; do not select the largest estimate.
- Role fit: name direct evidence and material gaps. A company's high total does
not remove a mandatory-skill gap or a user preference conflict.
Output contract
Preserve the current monthly report and HTML shell. For a new month copy the previous shell and update month-specific title, navigation, and links.
- Date (KST), search scope, weights, actual channel coverage and limits.
- Combined ranking first, with columns:
순위 | 회사 · 직무 | 공고 URL | 회사 위치 | 경력 · 마감 | 적합도 | 재무 | 복지·문화 | 연봉 정보 | 총점 | 한 줄 판단
Every URL opens the specific posting. Unknown locations remain [확인 필요]; do not substitute headquarters for an unknown worksite. Keep disputed hiring status visible in the row. Employment type may share the experience cell.
- Hiring-status findings for disputed listings, including evidence and next check.
- Detailed ranking evidence and dated new-scan sections, retaining older facts
with their dates. Merge new results instead of replacing prior sections.
- Verified-body candidates, body-unavailable candidates, exclusions with reasons,
and concrete next actions. Unread bodies get no invented fit score.
- Source paths and navigable report links; Korean plain language.
Write raw research to ai/sources/career/YYYY-MM-DD-de-posting-scan[-roundN].md and optional company-research notes. Update the durable shortlist's summary, decisions and open questions before finalizing the presentation. Reconcile stale summary claims such as "company research pending" when new facts supersede them. Update ai/worklog/YYYY/YYYY-Www.md and the relevant active-context pointer. An unused-market report never changes a submitted application's status by inference.
Render and verify
The normal wiki build does not render this career Markdown. Claude used Python-Markdown (tables, fenced_code) inside the existing HTML shell. From the repository root, this is the observed September regeneration procedure:
uv run --with markdown python - <<'PY'
from pathlib import Path
import markdown
stem = Path('human/career/2026-09-공고-후보') # Set the requested month.
source = stem.with_suffix('.md').read_text(encoding='utf-8')
target = stem.with_suffix('.html')
old = target.read_text(encoding='utf-8')
body = markdown.markdown(source, extensions=['tables', 'fenced_code'])
body = body.replace('<h1>', '<h1 class="doc-title">', 1)
start = old.index('<div class="quick">')
end = old.index('<footer class="foot">')
quick_end = old.index('</div>', start) + len('</div>')
new = old[:start] + old[start:quick_end] + '\n' + body + '\n' + old[end:]
target.write_text(new, encoding='utf-8')
PYBefore writing, reread shared files and preserve concurrent changes. Inspect the shell if its anchors differ; do not overwrite it with an unrelated design.
Completion checks:
- Recalculate every weighted score and tied rank; require a posting URL and
location or explicit unknown for every ranked row.
- Check duplicates, unknown markers, dates, and MD/HTML row parity. Verify each
recommendation is traceable to a source; state coverage gaps plainly.
- Run
python3 scripts/check_human_voice.py --stricton the changed career
Markdown and HTML; fix BAN/STRUCT and review WARN in context.
- For a changed HTML output, serve
human/locally and inspect the report in a
browser at desktop/mobile widths: Korean text, wide-table scrolling, direct posting links, and return navigation. Follow the available visual-QA skill.
- A local change is not a deployment. Publish only within the user's actual
authorization, and verify the live page before reporting publication.
For a workflow-only change, a temporary render compared against the reference HTML plus ranking checks validates the reconstruction without changing market facts or touching the published report.