Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions modes/apply.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,28 @@ Interactive mode for when the candidate is filling out an application form in Ch
2. IDENTIFY → Extract company + role from the page
3. SEARCH → Match against existing reports in reports/
4. LOAD → Read full report + Section G (if it exists)
5. COMPARE → Does the role on screen match the one evaluated? If it changed → notify
5. PREFLIGHT → Confirm posting liveness + company/role match before drafting
6. ANALYZE → Identify ALL visible form questions
7. GENERATE → For each question, generate a personalized response
8. PRESENT → Show formatted responses for copy-paste
```

## Step 5 — Preflight gate

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Critical: Duplicate "Step 5" heading.

The document contains two sections both labeled "Step 5":

  • Line 23: "## Step 5 — Preflight gate"
  • Line 77: "## Step 5 — Generate responses"

When the preflight gate was inserted as Step 5, subsequent sections were not renumbered. This breaks the documentation structure and will confuse users following the workflow.

📝 Proposed fix: renumber subsequent sections
-## Step 5 — Generate responses
+## Step 6 — Generate responses

And update the final section:

-## Step 6 — Post-apply (optional)
+## Step 7 — Post-apply (optional)

Also applies to: 77-77

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@modes/apply.md` at line 23, The document has two identical headings "## Step
5 — Preflight gate" and "## Step 5 — Generate responses"; rename the later
heading "## Step 5 — Generate responses" and all subsequent step headings to
increment their step numbers (e.g., change "## Step 5 — Generate responses" to
"## Step 6 — Generate responses" and bump following steps accordingly) so the
sequence is unique and sequential; update any internal references or cross-links
that mention the old step numbers to match the new numbering.


Before generating any application answers, verify that the form still points to the intended active job. This gate runs after the page has been detected, the company/role has been identified, and the matching report has been loaded.

1. Read the visible URL, page title, company, role, and any closed/expired signals.
2. If a URL is available, verify liveness with Playwright:
- active posting evidence: title/role + job description or form fields + submit/apply path
- closed posting evidence: expired/closed/no longer accepting applications, missing JD with only nav/footer, hard redirect to generic careers/search, or 404/410
3. Compare the visible company and role against the matched report.
4. If company or title changed materially, stop before drafting and ask:
"The form appears to be for [visible company] — [visible role], but the matched report is [report company] — [report role]. Do you want me to re-evaluate, adapt with this mismatch, or stop?"
5. If the posting appears closed, refuse to generate final copy unless the candidate explicitly overrides with a known reason.
6. If liveness cannot be verified because the candidate only pasted questions or a screenshot, state that limitation and ask the candidate to confirm the company, role, and active posting before drafting.

Do not continue to Step 6 until this preflight is resolved.

## Step 1 — Detect the job

**With Playwright:** Take a snapshot of the active page. Read title, URL, and visible content.
Expand All @@ -41,11 +57,11 @@ Interactive mode for when the candidate is filling out an application form in Ch

If the role on screen differs from the one evaluated:
- **Notify the candidate**: "The role has changed from [X] to [Y]. Do you want me to re-evaluate or adapt the responses to the new title?"
- **If adapt**: Adjust responses to the new role without re-evaluating
- **If adapt**: Adjust responses to the new role without re-evaluating, only after the candidate explicitly accepts the mismatch
- **If re-evaluate**: Execute full A-F evaluation, update report, regenerate Section G
- **Update tracker**: Change role title in applications.md if applicable

## Step 4 — Analyze form questions
## Step 6 — Analyze form questions

Identify ALL visible questions:
- Free text fields (cover letter, why this role, etc.)
Expand All @@ -67,7 +83,8 @@ For each field, preserve the application form contract:

Never invent answers for legal, demographic, work-authorization, visa/sponsorship, salary, disability, veteran, background-check, relocation, or self-identification fields. If the answer is not present in `config/profile.yml` or visible context, mark it as needing candidate confirmation and provide the safest question to ask the candidate.

## Step 5 — Generate responses

## Step 7 — Generate responses

For each question, generate the response following:

Expand Down Expand Up @@ -101,7 +118,7 @@ Notes:
- [Personalization suggestions the candidate should review]
```

## Step 6 — Post-apply (optional)
## Step 8 — Post-apply (optional)

If the candidate confirms that they submitted the application:
1. Update status in `applications.md` from "Evaluated" to "Applied"
Expand Down
13 changes: 13 additions & 0 deletions test-all.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,19 @@ if (shared.includes('_profile.md')) {
fail('_shared.md does NOT reference _profile.md');
}

const applyMode = readFile('modes/apply.md');
if (
applyMode.includes('## Step 5 — Preflight gate') &&
applyMode.includes('verify liveness with Playwright') &&
applyMode.includes('matching report has been loaded') &&
applyMode.includes('Do not continue to Step 6 until this preflight is resolved') &&
applyMode.includes('refuse to generate final copy')
) {
pass('apply mode includes liveness and role-match preflight gate');
} else {
fail('apply mode missing liveness/role-match preflight gate');
}

// ── 9. LOCAL PARSER CONTRACT ────────────────────────────────────

console.log('\n9. Local parser contract');
Expand Down
Loading