feat(input): normalize job descriptions

This commit is contained in:
2025-10-15 16:53:58 -05:00
parent 392daff8cc
commit 599821d25a
6 changed files with 223 additions and 74 deletions

View File

@@ -4,27 +4,29 @@ The input side of ResumeCustomizer prepares job-specific Markdown resumes by sti
## Workflow Recap
1. Ensure `input/resume/` contains exactly one Markdown resume.
2. Drop a single job-description Markdown into `input/ForCustomizing/inbox/`.
2. Drop a single job-description file (plain text or Markdown) into `input/ForCustomizing/inbox/`.
3. Start the watcher stack (`input/Docker/run-input-processor.sh up -d`).
4. The watcher combines the resume, job description, and the resolved instruction prompt (defaulting to `templates/ResumeCustomizerPrompt.md.example`) into a prompt, runs the Codex CLI, and writes the generated resume to `ForCustomizing/outbox/YYYY/MM/DD/HHMM/`.
5. Successful runs archive the job description under `ForCustomizing/processed/` and copy the prompt used into the same outbox folder. Failures move the job description into `ForCustomizing/failed/` for review.
4. The watcher normalizes the messy job description via Codex (using `templates/JobDescriptionNormalizerPrompt.md.example` by default), then combines the cleaned Markdown, the base resume, and the resolved customization prompt into a second Codex run that writes the generated resume to `ForCustomizing/outbox/YYYY/MM/DD/HHMM/<company>-<jobtitle>.md`.
5. Successful runs archive the job description under `ForCustomizing/processed/`, copy both the prompt and the cleaned job description into the same outbox folder, and leave the Codex output for human review. Failures move the job description into `ForCustomizing/failed/`.
The human operator reviews the Codex output Markdown, makes any edits, and then manually hands it off to the output pipeline for document rendering.
## Container Stack
The watcher lives in `input/Docker/`:
- `Dockerfile` builds a Node/Python base image, installs gosu, and prepares a non-root `codex` user.
- `watch_and_customize.py` polls the inbox, validates preconditions, resolves the prompt template (`ResumeCustomizerPrompt.md` or its `.example` fallback), constructs prompts, runs Codex, and routes files.
- `watch_and_customize.py` polls the inbox, validates preconditions, resolves both templates (normalizer and customization), cleans the job description, builds prompts, runs Codex twice, and routes files.
- `entrypoint.sh` maps the container user to the callers UID/GID and ensures shared directories exist.
- `run-input-processor.sh` wrapper around `docker compose` that mounts your `~/.codex` directory and forwards CLI arguments.
- `docker-compose.yml` defines the container, volumes, environment variables, and restart policy (`no` so fatal errors halt the stack).
### Templates
- `templates/ResumeCustomizerPrompt.md.example` ships with default Codex instructions.
- To customize, copy the `.example` file to `templates/ResumeCustomizerPrompt.md` (the `.gitignore` keeps your local overrides out of version control).
- `templates/JobDescriptionNormalizerPrompt.md.example` ships with default instructions that clean recruiter chatter and extract company/role details. Copy it to `JobDescriptionNormalizerPrompt.md` to override.
- `templates/ResumeCustomizerPrompt.md.example` ships with default resume-customization instructions. Copy it to `ResumeCustomizerPrompt.md` to override.
- The `.gitignore` in `templates/` keeps local overrides out of version control.
### Key Environment Variables
- `CODEX_COMMAND_TEMPLATE` format string for invoking Codex (placeholders: `{prompt}`, `{output}`).
- `CODEX_COMMAND_TEMPLATE` format string for the resume-customization Codex run (placeholders: `{prompt}`, `{output}`).
- `CODEX_NORMALIZER_COMMAND_TEMPLATE` optional override for the normalization Codex run (defaults to `CODEX_COMMAND_TEMPLATE`).
- `POLL_INTERVAL_SECONDS` watch loop delay (defaults to 5).
- `CODEX_TIMEOUT_SECONDS` wall-clock timeout for each Codex call (defaults to 600).
- `CODEX_CONFIG_DIR` host path to mount as `/home/codex/.codex` (defaults to `${HOME}/.codex` via the wrapper).