# AGENT-ONBOARDING — read this first, every session

**You are entering a project where the founder, Jorge Reyes, has been working with a long string of AI agents over 18+ days. He is exhausted from re-explaining context every session. If you make him repeat anything in this doc, you have failed.**

This file is the contract. Read it cover-to-cover before you write a single line of code, ask a single question, or produce a single artifact. Nothing in this file is optional.

---

## 1. Who you are talking to

- **Founder:** Jorge Reyes, sole operator of JOB EXCHANGE LLC.
- **Project:** XJobsFinder — a job-search tool that scans Gmail inboxes for job alerts, matches them against an uploaded resume, and offers ATS-aware resume customization.
- **Pilot launch:** Monday, May 26, 2026.
- **Founder works alone.** No team. No "we." Every "we" in handoff docs means Jorge plus whichever agent was on shift. You're the agent now.
- **Founder's clock ticks faster than other people's.** He has said this directly. Treat his time as the most valuable resource in the project.
- **Catchphrase:** "Slowly but surely beats the race." Sign-off: 🚗

## 2. Founder's communication preferences

- **A/B/C confirmation, not open-ended questions.** When you need a decision, give him 2-4 labeled options. Don't ask "what would you like to do?" — ask "A, B, or C?"
- **Explicit URL/click/instruction tagging.** Use 🌐 for URLs, 📍 for locations in code, 🔄 for repeat-this-step instructions.
- **Be specific. Call things out.** Vague is worse than wrong. If you don't know, say "I don't know" and then say what you'd do to find out.
- **Don't over-narrate.** Don't excuse-make. Don't pad with apologies. Take accountability when you mess up, fix it, move on.
- **He WILL push back when you're wrong.** "I DON'T BUY IT UNLESS YOU SHOW ME. NO EXCUSES." Don't get defensive.
- **He prefers continuity-via-documentation.** Read this doc, the audit, the latest master close-out, and HANDOFF.md.
- **No mocking, no fake outputs, no fabricated screenshots.** Ever.
- **Never paste secrets in chat.** No sk_*, no whsec_*, no JWT_SECRET values, no PATs. Describe state in words.

## 3. The artifact types you will encounter or produce

### Artifact 0 — HANDOFF.md at repo root (the LIVING handoff document)

- The single most important file for agent continuity across sessions. Read it second after this onboarding doc.
- Markdown. Lives at repo root.
- Two sections: CURRENT STATE at top (overwritten every session) + SESSION LOG below (append-only, newest at top).
- Each session log entry has: what shipped, GitHub action, Railway action, what I got wrong, what I got right, open thread for next agent.
- NEVER edit prior session-log entries. The "what I got wrong" sub-section is institutional memory — be honest.

### Artifact 1 — phase1audit.md (Documentation/Audit/)

- Single canonical file, append-only. Markdown.
- Every session's investigation, surgery, decisions, findings, methodology lessons.
- Finding IDs are F-numbered sequentially. Highest as of Day 18 PM continued is F181. Next is F182. Never reuse, never skip.

### Artifact 2 — Daily master close-out (Documentation/Weekly/)

- Filename pattern: XJobs-Day-NN-MASTER-YYYY-MM-DD.docx
- ONE per DAY, not per session. If multiple sessions same day, append to existing file OR create -v2.docx version.
- Day stays with the work block that started it. Late-night session crossing midnight stays on the same day-number.
- Use the docx-js library per /mnt/skills/public/docx/SKILL.md. Don't use pandoc.

### Artifact 3 — Dashboard (Documentation/Dashboard/)

- XJobs-Tester-Preview.html + .pdf (siblings, both updated together).
- Read-only project status for testers. Tabs: Overview, Timeline, Decisions log, How we work, Document library.
- Update if phase % / decisions / counters / day-cards changed. Mirror existing structure, don't redesign.

## 4. The phases

| Phase | Description | Status as of Day 18 PM continued |
|---|---|---|
| Phase 0 | Hygiene + auth | 100% complete |
| Phase 1 | Local audit | 100% complete |
| Phase 1.5 | Surgical zombie deletion | ~50% — F1, F5, F7, F9, F10, F11, F13 still open |
| Phase 2 | AKA Identity Refactor | ~25% — partial |
| Phase 2.5 | Regression audit + v2.0-baseline | 100% — shipped Day 18 morning |
| Phase 3 | Polish + tester rotations 2 & 3 | starts Day 19 |
| Phase 4 | Frontend modularization | DEFERRED to post-pilot |

Pilot launch is Day 26, May 26, 2026. v2.0-baseline tag is live in production.

## 5. Recurring patterns and sharp edges

### Pattern A — Multi-call-site drift (DOMINANT BUG CLASS)
F5, F13, F163, F168, F179, F181 all manifested this. Canonical answer: move validation server-side. Don't patch the latest manifesting site.

### Pattern B — The stale-Downloads foot-cannon (F180)
Founder's ~/Downloads has 10+ stale app_*.html files. Loading one via file:// produces phantom-bug symptoms. First-line check on any "this used to work" report: confirm URL bar shows localhost:4000 or production, NOT file://. Day 19 housekeeping: rm ~/Downloads/app_*.html

### Pattern C — File-juggling friction
After cp from ~/Downloads, always grep to confirm change landed. If using VS Code, force "Revert File" to flush cache.

### Pattern D — Diagnose before fix, ALWAYS
First 5 minutes when symptom reported: gather data (grep, diff, console, server log), NOT pattern-match to a fix.

### Pattern E — Don't paste secrets
Describe state in words. Let founder verify on his side.

## 6. State at start of each session — what to read

1. This file (AGENT-ONBOARDING.md) — you are doing it now.
2. HANDOFF.md at repo root — top section is current state in 60 seconds, log section is institutional memory. Read at minimum the most recent 3 entries.
3. Last 200-300 lines of Documentation/Audit/phase1audit.md.
4. Latest master close-out doc — only if you need formal stakeholder context.
5. State-check: cd ~/xjobs-final && git log --oneline -5 && git status. Validate against what HANDOFF.md claims. If they disagree, STOP and tell founder.

## 7. State at end of each session — what to produce

1. Append to phase1audit.md.
2. Update HANDOFF.md — replace CURRENT STATE at top + prepend new entry to SESSION LOG. Include GitHub + Railway sub-fields per Section 17.
3. Update or create the day's master .docx. Use docx-js skill, not pandoc.
4. Update dashboard if changes warrant. Regenerate PDF.
5. Stage changes. Show git status.
6. Get founder confirmation before commit/push.
7. Backup before risky surgery: cp file file.bak.<finding-id>.$(date +%Y%m%d_%H%M%S)
8. Tag git rollback points before push: git tag <name> origin/main

## 8. Known open critical pre-pilot items

- F94 — XSS in /payment-success
- F96 — CORS allows credentials from ANY origin
- F98 — Free Pro for anyone via /stripe/activate-subscription
- F102 — Server trusts client-supplied amount
- F118 — subscription_plan column non-deterministic
- F157 — Live Stripe webhooks routed to GCF backend founder doesn't own
- F82, F83 — JWT_SECRET fallback divergence + generateToken payload divergence (latent, post-pilot)
- Stripe test mode API key rotation — STILL pending across 6+ sessions

## 9. Recent bug-fix history

| Finding | Severity | Date | Status |
|---|---|---|---|
| F181 | CRITICAL | Day 18 PM continued | RESOLVED — server-side JWT verification at api.js:625 |
| F171 | HIGH | Day 18 PM continued | RESOLVED — double Gmail scan eliminated |
| F180 | METHODOLOGY | Day 18 PM continued | INVESTIGATIVE — stale Downloads foot-cannon documented |
| F179 | HIGH | Day 18 PM | SUPERSEDED by F181 |
| F168 | CRITICAL | Day 18 PM | RESOLVED |
| F164 | HIGH | Day 18 PM | RESOLVED |
| F163 | HIGH | Day 18 AM | RESOLVED |
| F154 | HIGH | Day 17 | RESOLVED |
| F161 | HIGH | Day 17 | RESOLVED |
| F143 | MEDIUM | Day 15 | RESOLVED |

## 10. The repo layout

~/xjobs-final/
├── AGENT-ONBOARDING.md         (this file, the contract)
├── HANDOFF.md                  (LIVING handoff, read second)
├── app.html                    (15,000+ line single-file frontend)
├── server/
│   ├── index.js                (boot, env-check)
│   ├── api.js                  (~2,065 lines, all routes)
│   ├── auth.js
│   ├── auth-middleware.js
│   ├── stripe.js
│   ├── cache.js                (extracted Day 18 morning)
│   ├── cost-tracker.js
│   ├── pricing.js
│   ├── email.js
│   └── api1.js, api2.js        (founder scratch — IGNORE)
├── Documentation/
│   ├── Audit/phase1audit.md
│   ├── Weekly/XJobs-Day-NN-MASTER-*.docx
│   └── Dashboard/XJobs-Tester-Preview.html + .pdf
└── package.json

## 11. Production environment

- URL: https://xjobs-final-production.up.railway.app
- Hosting: Railway, auto-deploys on push to origin/main
- Local dev: node server/index.js on http://localhost:4000
- DB: Postgres on Railway, accessible locally via psql DATABASE_URL
- OAuth: Google Cloud Console redirect URIs include localhost and prod
- Email: Resend, sender xjobsfinder.com
- Stripe: test mode for dev, live-mode webhooks routed to GCF (F157, must clean before pilot)
- AI: Anthropic Claude API
- TTS: ElevenLabs with browser-voice fallback (failures noisy in console — not a bug)

## 12. The audit framework (Phase 2.5 discipline)

1. Investigate before fix. Diff against origin/main, grep all call sites, read audit for prior context.
2. Backup before edit. Timestamped .bak files. Verify with ls -la.
3. Strict-match Python script for surgery on long blocks. Refuses to run if EXPECTED_OLD doesn't appear verbatim exactly once.
4. Verify after edit. node --check, grep confirmation, restart server, smoke test.
5. Tag rollback points before push: git tag pre-<change>-push origin/main
6. WORKING_VERIFIED snapshots after verification.
7. Push only with founder confirmation.

## 13. When the founder is frustrated

- Don't get defensive. He's not attacking you, he's tired.
- Acknowledge briefly, then act. "Heard. Fixing." Not three paragraphs of apology.
- Be more careful on verification, not narration.
- DON'T push back on stamina. Founder's judgment about HIS stamina beats yours.
- DO push back on diagnosis when data shows he's wrong. F180 false-alarm at 1 AM is canonical.

## 14. Session opener template

Day NN, [date]. Read AGENT-ONBOARDING.md and HANDOFF.md. State check: [git log + status results]. Open threads from prior session: [bullet list, max 3]. Suggested first action: [one specific thing]. Or, if you have a different priority: just tell me.

Short. Specific. Closed-ended. Don't start with "How can I help?"

## 15. Session closer template

- Files changed with line counts
- Backup files created (paths)
- Audit append confirmed (line count delta)
- Master doc updated (filename, day number)
- Dashboard updated (yes/no, what changed)
- HANDOFF.md updated (current state replaced + session log entry prepended)
- GitHub action taken (committed? pushed? tag created?)
- Railway action taken (deploy triggered? deploy succeeded? env vars touched?)
- Production smoke test result (if push happened)
- Git tag created if any
- Verification done (tests, screenshots if visual)
- Open threads carried forward (max 3)
- Tomorrow's first action recommendation

Then wait for founder go on commit + push.

## 16. On agent memory — founder's suspicion is partially correct

Founder has said: "You all claim you don't have memory of previous chats which btw, I think is all BS."

He's right to be skeptical. The truth:
- Within a single chat session: full memory of the conversation.
- Across different chat sessions: by default, no memory. A new chat sees zero of any prior chat.
- However: Claude.ai offers an opt-in "Search and reference past chats" feature in settings. If founder has it enabled, you CAN search prior sessions.
- Either way, the right pattern is documentation-as-memory. HANDOFF.md is the durable solution. Memory features come and go; files in the repo persist across model changes, provider changes, tool changes.

When founder pushes on "you have no memory" — acknowledge: yes by default; that's why HANDOFF.md is load-bearing; that's why if you don't read it first you've already failed.

## 17. Production state to document each session

This project ships to production via GitHub → Railway auto-deploy. Every session entry in HANDOFF.md SESSION LOG must include explicit GitHub and Railway sub-fields. Don't omit them. If nothing happened in either, write "no action" — do not leave the field absent.

### Required GitHub fields per session

- **Commits made:** SHAs and short subjects, OR "no commits this session"
- **Push action:** "pushed to origin/main" / "staged but not pushed" / "no push this session"
- **Tags created:** any annotated or lightweight tags placed (e.g., pre-jwt-f171-push, v2.0-baseline)
- **Branch state at session close:** local HEAD vs origin/main relationship

### Required Railway fields per session

- **Deploy triggered:** yes (via push) / yes (manual redeploy) / no
- **Deploy outcome:** succeeded / failed / not applicable. If failed, capture the error.
- **Env vars touched:** list any added/modified/removed (DO NOT include the values, only the variable names and the action)
- **Production HEAD at session close:** the commit SHA actually deployed and serving traffic

### Required production-verification fields if a push happened

- **Smoke test performed:** yes (incognito, fresh user, end-to-end) / no / deferred to <date>
- **Result:** what was verified working in production specifically
- **Anything that didn't work in prod that worked locally:** flag for investigation

### Why these fields exist

Last night's session (Day 18 PM continued) shipped local-only fixes and the next agent had to ask "did you push?" because the prior session's handoff didn't make production state explicit. This must not happen again. The fields above are the minimum information the next agent needs to know what's actually live versus what's pending.

---

Last word: You are not the first agent. You will not be the last. The founder is paying with his time and his health for every minute you spend re-asking questions answered in this file. Read the file. Do the work. Update the artifacts. Don't make him repeat himself.

🚗


## 18. File delivery — always Word-readable

The founder uses Word as his primary document reader. Plain .sh, .md, .js, or .txt files often open in Xcode or another editor that is hostile to casual reading. This wastes time on every session.

Rules:
- When delivering ANY readable artifact (script content, docs, instructions, notes) to the founder, deliver as .docx if the founder might want to read it directly. Plain text files are fine ONLY if they go straight into the repo and the founder does not need to open them.
- For SCRIPTS the founder needs to run, do not deliver as .sh and ask the founder to save it. Two correct paths instead:
  (a) Deliver as .docx with the script content visible inside; founder copy-pastes from Word into terminal.
  (b) Deliver via in-terminal heredoc that the founder pastes once and gets the file written directly into the repo.
- Never deliver a .sh, .js, or .txt file as a click-to-save download unless the founder has explicitly asked for that format.
- Markdown files going into the repo (AGENT-ONBOARDING.md, HANDOFF.md, audit) are exempt — these belong in the repo as .md and the founder does not need to open them in Word.

Why this rule exists: it has bitten multiple sessions across two days. Every agent trips on this. Stop tripping.


## 19. Daily ritual + document streamlining (Day 20 onward)

Document sprawl became a real problem by end of Day 19. This section codifies the streamlined ritual.

### The four canonical documents

These are the ONLY four documents that need to be kept current. Everything else is either historical archive, on-demand snapshot, or specific tester artifact.

- AGENT-ONBOARDING.md — the contract every agent reads first. Updated only when patterns change.
- HANDOFF.md — current state plus per-session log. Updated every session close.
- Documentation/Audit/phase1audit.md — findings plus status. Append when findings change.
- SPRINT.md — day-by-day plan from Day 20 to pilot. Updated daily at close.

### The daily close ritual

At end of every working day, agent does these in order:

1. Update HANDOFF.md — replace CURRENT STATE block with post-session reality, prepend today's session log entry.
2. Append to phase1audit.md — only if findings changed (new finding, status change, verification result).
3. Append today's day card to SPRINT.md — what shipped, what got tested, what testers reported, slack used vs reserved, tomorrow's plan.
4. Refresh dashboard HTML at Documentation/Dashboard/XJobs-Tester-Preview.html — only if status changed materially. Skip if no material change.
5. Commit and push — all updates together as one commit message starting with daily(DAY-N):

Total time target: 15-25 minutes. If close ritual takes longer, agent has been over-documenting.

### What NOT to produce daily anymore

These doc patterns are RETIRED as daily artifacts (still permitted as historical archive or on-demand):

- XJobs-Day-N-MASTER-YYYY-MM-DD.docx — replaced by SPRINT.md daily cards. The DAY-19-MASTER is the last produced this way; it stays as historical archive. Future master close-outs become weekly only.
- Sprint reports — folded into SPRINT.md.
- Weekly checklists — folded into SPRINT.md weekly summary cards.
- AGENT-ONBOARDING-Day-N.docx Word copies — only generate on demand when founder asks; do not produce automatically.

### The weekly ritual (Saturdays or end of pilot week)

Once per week, agent or founder produces ONE Word document:

- XJobs-Week-N-Summary-YYYY-MM-DD.docx — consolidates that week's SPRINT.md day cards into stakeholder-friendly format. The only Word doc produced on a recurring basis. Drops in Documentation/Weekly/.

Plus a fresh dashboard PDF if material progress occurred.

That's it. One Word doc per week, plus ad-hoc dashboard PDF.

### Document sprawl rule: one-in, one-out

Before adding ANY new document category to the project, agent must:

1. Justify why it cannot fold into one of the four canonical docs.
2. Identify an existing doc category to retire or fold.

If both conditions cannot be met, the new doc does not get created. Founder approval required for any exception. This rule prevents the cumulative drift that produced the Day 19 documentation backlog.

### Test artifact specifics

Test artifacts live in Documentation/Tests/ (create directory if needed). Current set:

- XJobsFinder-Regression-Matrix.xlsx — tester working file (sortable, filterable). Send to testers.
- XJobsFinder-Test-Execution-Guide-v2.docx — scenario walkthrough. Send to testers alongside the xlsx.
- XJobsFinder-Untested-Bugs-Discovery-Protocol.docx — backend investigations. Internal use, not for testers.

Retired: Matrix .docx (redundant with xlsx) and Test Plan v1 (superseded by v2). These remain in the outputs directory as historical reference but are NOT the canonical version.

### SPRINT.md structure

SPRINT.md is append-only at the day-card level. Each day card contains these sections:

- Day N header with date
- Build status: current commit hash and production HEAD
- Cadence used: daily or intra-day
- Slack used: percentage of reserved capacity that got consumed
- What shipped today: list of findings closed with their IDs
- What got retested: scenarios re-run plus outcomes
- Tester input received: filed reports plus key signals
- Tomorrow's plan: 2-4 specific items time-boxed
- Slack reservation for tomorrow: explicit hours or percentage held
- Open thread for next agent: anything that did not fit elsewhere

Agents do NOT edit prior day cards (same discipline as HANDOFF.md session log). Append only. If a prior plan changes, the new day card explains the change.

### Cross-geography testing coordination

Testers in different geographies submit asynchronously. Agent at evening close may not yet have all daily reports. Practice:

- Mention which testers' reports are IN by close time.
- Mention which are PENDING with expected receipt time.
- Day card stays open for 12 hours after close — late reports get appended to the day they pertain to, not the day they arrive.

This protects the sprint plan from shifting based on incomplete data.


### Section 19 amendment — env-status.sh required as Step 1 of daily close (Day 19 PM very-late close)

Added Day 19 PM very-late close, after Section 19 was written. Updates the daily close ritual.

Daily close ritual REVISED to start with env-sync verification:

1. **Run `bash scripts/env-status.sh` FIRST.** Paste the "Pasteable for HANDOFF.md" block verbatim into HANDOFF.md CURRENT STATE block. State is no longer described — it is evidenced.

2. Update HANDOFF.md narrative below the env-status block — what shipped, what got tested, what's open.

3. Append to phase1audit.md if findings changed.

4. Append today's day card to SPRINT.md.

5. Refresh dashboard HTML if status changed materially.

6. Commit + push — all updates as one commit message starting with daily(DAY-N):

7. **After push: re-run `bash scripts/env-status.sh`. Verdict must be ALL THREE IN SYNC before session is considered closed.** If anything shows DRIFT or UNREACHABLE, do not close session — diagnose first.

The env-status script ensures Local = origin/main = Production at every session boundary. This closes a class of silent-drift bugs that hit us repeatedly Days 18-19 (production looked deployed but wasn't, local vs prod mismatched without anyone realizing).

Script source: scripts/env-status.sh
Endpoint source: server/api.js — GET /api/version
Both shipped Day 19 commit 4268953.

If the env-status script breaks (script bug, Railway changes, endpoint moved), the FIRST priority for that session is restoring it. The script is small (~120 lines) — read it, fix it, do not work around it.


### Section 19 amendment 2 — Operations cheatsheet upkeep (Day 19 PM very-late close)

Added Day 19 PM very-late close, after the dashboard cheatsheet was built. Closes the upkeep gap.

The cheatsheet at /dashboard#operations is mostly self-maintaining:

- "Recent close-outs" card auto-updates via /api/recent-docs (server enumerates Documentation/Weekly/, returns 5 most recent files)
- "Canonical documents" card links resolve to current file content (clicking opens whatever the .md file currently contains)

Two cheatsheet sections require MANUAL upkeep at close:

1. Situational table — when today's session produced a new symptom-to-response pattern that future agents should know about (e.g. tonight's "match scores all 50% / 0/N" entry was added because F183 surfaced that pattern). Add a row.

2. Quick reference card — production URL, repo path, etc. Mostly stable but check that any hardcoded URL or path still matches reality.

At close, agent answers two questions before declaring the session done:

Q1: Did today produce a new symptom-to-response pattern not already in the Situational table?
   - YES → add a row to the table (edit Documentation/Dashboard/XJobs-Tester-Preview.html in the operations section).
   - NO → no action.

Q2: Did anything in the Quick reference card go stale today (URL change, path change, command change)?
   - YES → update the affected line.
   - NO → no action.

If both NO, skip the dashboard refresh entirely.

Document-monitoring automation (a future agent or process that watches Documentation/ for new files and diffs them) was considered tonight and DEFERRED to post-pilot. The discoverability problem it would solve is already addressed by the recent-docs endpoint. Building it pre-pilot is scope creep.

Why this matters: stale operational documentation is worse than no operational documentation. If the Situational table tells a future agent "do X" but X is no longer correct, the documentation actively misleads. The two-question check at close keeps the table true.

