# Codex prompt — adversarially walk the AI Sales Workspace

Paste everything below the line into Codex. It is written to make Codex *use*
the product as two different people and report what does not hold up — not to
review the diff.

---

You are auditing a feature branch of a Laravel + Inertia + Vue CRM by **using
it**, not by reading its diff. Read code only to confirm or refute something you
observed on screen or in a response body.

## Environment

- Repo: `~/Documents/GitHub/petav3-dev-chen-integration`, branch `dev-chen`
- Site: `https://petav3.test` (Herd; self-signed cert — pass `-k` to curl)
- PHP: **always** `herd php ...`. The terminal default is 7.4 and will fail.
- Assets are built (`public/build`). If you edit a `.vue`, run `npm run build`.
- Two demo accounts, password-less dev login:
  `POST /auth/dev-login` with `_token` (CSRF from the page's meta tag),
  `email`, `portal=manage`. It accepts any ACTIVE user's email.
  - `demo.sales@propertylab.test` — sales agent, owns the tasks
  - `demo.admin@propertylab.test` — super admin, sees the team
- Re-seed the demo data any time with:
  `herd php artisan tinker --execute="require '/private/tmp/claude-501/-Users-dadadineiyou/7e06f09f-d625-4736-8030-a7c1ea8456c9/scratchpad/seed_acceptance.php';"`

### Hard constraints

- **Never** run `migrate:fresh`, `db:wipe` or `migrate --force` against the dev
  database. `.env` points at `petav3_preview_20260722` and there is **no
  `.env.testing`**, so `--env=testing` silently falls back to it. If you need a
  scratch database, name it explicitly:
  `DB_DATABASE=petav3_scratch herd php artisan ...`
- **Never** run two `artisan test` processes at once — they both `migrate:fresh`
  the same test schema. After killing tests, `pgrep -fl phpunit` and kill any
  survivor; `pkill -f "artisan test"` does not reach the child.
- `./vendor/bin/pint` with no path reformats the whole repo. Always pass paths.
- Do not touch **Lead Discussion → Action Items** (`app/Http/Controllers/Manage/Leads/`).
  It is deliberately out of scope for this work.

## What the feature claims

One server-side source — `Src\Lead\Services\SalesWorkQueue` — owns every number
about outstanding follow-up work, so these surfaces cannot disagree:

| Surface | Path |
|---|---|
| Hub checklist card + sign-in agenda | `/manage/dashboard` |
| Action Items workbench (My Tasks / Team Tasks) | `/manage/action-items` |
| Zoom AI Agent | `/manage/zoom/ai-agent` |
| AI Employee → Analytics → Agents | `/manage/ai-copilot/analytics?tab=agents` |
| Action plan review (draft approval) | `/manage/zoom/actions` |

Claims worth attacking:

1. **One number.** All four surfaces report the same count of open follow-up
   steps for the same viewer. Completing one step moves all of them.
2. **Ordering.** Overdue → Today → Unscheduled → Upcoming, then priority, then a
   stable tie-break. Urgency outranks priority: a Low overdue step sits above a
   High undated one.
3. **Dates are confirmed, not guessed.** The AI proposes a date only where the
   conversation named a day; a reviewer confirms it; `scheduled_source` records
   which of the two happened. A past date from the AI is dropped, never clamped
   to today. A date a reviewer set that has since passed is kept and shows as
   overdue.
4. **Team Tasks is supervision, not execution.** It returns many customers at
   once, so it carries no phone, no WhatsApp link, no call payload — only "open
   the lead". My Tasks keeps Call / WhatsApp / Done / agree-disagree.
5. **Nothing claims more than it knows.** No conversion rates, no uplift. A
   pipeline product and its commission appear only after a human confirmed the
   match. Commission is Super-Admin-only. `data_completeness` travels as a count
   with its parts, never as a High/Medium/Low word.
6. **Provenance is never separated from the value it qualifies.** Priority shows
   with "AI suggested" / "Set by reviewer"; the compact view hides both or
   neither.
7. **Filters narrow what is shown AND say what they hid.** A team card under a
   filter reads "1 matching · 4 open".
8. **A lead never straddles a page.** Team Tasks pages by customer, 20 per page,
   with `next_offset` and a total.

## How to work

Spend most of your effort in the browser and on response bodies. For each claim:

1. Reproduce the happy path as **both** accounts. Note what you see.
2. Then try to break it. Some starting points, not a checklist — find your own:
   - Complete a step in one tab; do the other surfaces move?
   - Set a step's date to today, to yesterday, to next year. Cross midnight by
     changing `scheduled_for` directly in the database and reloading.
   - Approve a plan without touching anything. Does the UI still say the AI
     suggested the priority and the date, or does approval quietly launder them
     into human decisions?
   - Filter Team Tasks by every bucket. Do the numbers on the card, the summary
     line and the page agree?
   - `GET /manage/dashboard/checklist/team` as the super admin and grep the raw
     JSON for `phone`, `wa.me`, `tel:`, and a bare `60\d{9}`. Note that
     `action_type_label: "WhatsApp"` is a legitimate step TYPE, not contact data.
   - Reassign a lead to another salesperson and reload the first one's list. Can
     they still read the customer's name or the step text?
   - Ask for `?offset=` values that are negative, enormous, or not a number.
   - Give one customer 30 steps and page through. Is anyone duplicated or
     skipped?
   - Log in as the sales agent and try `/manage/dashboard/checklist/team`
     directly.
3. When something looks wrong, **confirm it before reporting**. Re-run it, check
   the response body, and read the code path. Distinguish "the seed data makes
   this look odd" from "the code is wrong".

## Two things that are true and may look like bugs

- Commission can legitimately be **unknown** (no priced booking). The card shows
  a dash and `data_completeness` says `Value: not present`. That is the system
  being honest, not a missing figure.
- `ai_credentials` is currently **empty**, so anything calling an AI provider
  ("Ask AI" in the review modal) fails with "I could not reach my AI provider".
  That is missing configuration in this environment, not a defect. Do not add
  keys; note it and move on.

## What to report

For each finding:

- **What you did**, exactly enough that someone can repeat it.
- **What you expected and what happened.** Quote the response body or the screen
  text.
- **Which claim above it violates**, or "new" if it violates none.
- **How sure you are, and what would change your mind.** Say "I could not
  reproduce this a second time" when that is the case.
- **Severity in terms of who is misled** — a manager reading a wrong backlog
  number is worse than a misaligned badge.

Then, separately:

- **Claims you tried hard to break and could not.** Name the attack, so the next
  reader knows it was tested rather than assumed.
- **Anything confusing that is not a bug** — a label you had to read twice, a
  number you had to derive. This product's whole thesis is that its numbers mean
  one thing; wording that makes a reader guess is a real finding even when the
  code is right.

Do not fix anything. Do not commit. Report only.
