PlanOmatic Operations · agent console

Zillow Floorplan Agent

Access is enforced on the server per role. This screen only signs you in; it does not decide what you may reach.
Security

Set a new password

Your account requires a password change before you can continue.
PlanOmatic Operations
Launch posture: —
0/0 wired · 0 dead
—
Admin
Zillow Floor Plan

What this tab is for: a PlanOmatic admin assigns people to roles and decides which tabs each role can see, across BOTH agent boards. Roles are fully configurable here — create, rename, delete, and re-grant. Access is enforced on the server per role; hiding a tab in the UI is not access control.

Roles & page accessi

Fully configurable. Add a role, rename or delete one, and tick to grant a page. Roles are referenced internally by a stable ID, so a rename only changes the label.
GET/api/roles · /api/pages
CRUDPOST /api/roles · PUT /api/roles/{role_id} · DELETE /api/roles/{role_id}
GRANTGET/PUT /api/roles/{role_id}/tabs (stable ID, never a name)
Sourceroles, role_tab_grants (config)
Effectserver-side gates each route per role, every request, FAIL-CLOSED
Statepending

Peoplei

Add a user, assign a role, or deactivate. Access follows from the assigned role.
GET/api/users
CRUDPOST /api/users · PUT /api/users/{id}/role · POST /api/users/{id}/deactivate
Sourceusers, roles (config)
Effectsets the user's role; tab access derives from the grants
Statepending

What this tab is for: how the agent is performing — how much it processed, how good its QA calls turned out to be, and where it needs tuning. Everything here is read-only.

Time window
i

Month over monthi

Processed volume by month, split pass / review / fail (last 12 months).
passedreviewfailed
GET/api/metrics/timeseries?bucket=month&months=12
Sourceqa_results
Effectrenders monthly series
Statepending

QA check performancei

Per-check flag volume, trend, and how often a human upheld the agent's flag. This is where to look to improve QA.
#CheckFlags (window)6-mo trend Human agreement i
GET/api/metrics/checks?window=&trend=6mo
Sourceqa_results.check_results ⋈ operator outcomes
Effectrenders per-check volume + agreement
Statepending

QA calibration — the agent's report cardi

Agent verdict (cf 73) versus the operator's final action (cf 70). Green cells are agreement; red cells are the misses to watch.
GET/api/metrics/calibration?window=
Sourceqa_results.cf73 ⋈ jobs.cf70 (Order cf 2)
Effectrenders matrix + derived rates
Statepending

Lifecycle state (cf 70)i

Current distribution across the Floor Plan Status values.
GET/api/jobs?group=fp_status
Sourcejobs.cf70
Effectrenders counts
Statepending

What this tab is for: the settings that change how the agent behaves. A control marked not wired below is audited and confirmed inert (ROUTING 157): the round-trip may succeed, but no code the agent runs reads it back, so editing it changes nothing. Every other control here takes effect on the agent's next run and is the live source of truth, not just this screen.

Run modei

Global safety posture and cadence.
GET/PUT/api/controls/{REVIEW_MODE, DRAFT_ONLY_qa, poll_interval_s}
Sourcenone; no config row exists under any of these three names (ROUTING 157 audit)
EffectNOT WIRED; see notice below
Statepending

Matching & timeoutsi

The address bridge and the two watchdogs. The matcher is deterministic: house number + street name must agree after normalization. There is no similarity score and no confidence threshold — the normalization tolerance table is the only matching tunable.
GET/PUT/api/controls/{address_normalization_tolerance NOT WIRED, timeout_hours NOT WIRED, marked_addressed_return_hours}
Sourcemarked_addressed_return_hours only → escalations view bucketing (§9a); the other two resolve no config row (ROUTING 157 audit)
Effectmarked_addressed_return_hours moves which HITL bucket an item shows in NOW, but not the agent's own automatic revert timer, which is separately configured; the other two controls are not wired
Statepending

QA check severity & enablementi

Set each check to Fail (marks the floorplan failed) or Review (sends it to a person), or switch it off. Human-only checks always go to a person — the agent can't judge them from the image — so their severity is locked at Review.
#CheckSeverityEnabled i
GET/PUT/api/controls/{qa_check_<id>_severity, qa_check_<id>_enabled}
Sourcenone; the QA engine reads qa.check.<id>.severity / .enabled (dotted), a different, never-read name (ROUTING 157 audit)
EffectNOT WIRED; neither the read nor the write reaches the QA engine, see notice below
Statepending

Label dictionaries & termsi

Editable lists the QA engine reads.
GET/PUT/api/controls/{room_dict, unique_labels, repeatable_labels, terms_to_avoid, disclaimer_ref}
Sourcenone; the QA engine reads qa.dict.room_dictionary / qa.dict.unique_labels / qa.dict.repeatable_labels / qa.term_to_avoid.terms / qa.disclaimer.reference_text, different, never-read names (ROUTING 157 audit)
EffectNOT WIRED; see notice below
Statepending

Per-client rulesi

Base profile plus per-client overrides.
GET/api/controls/client_rules/{client}
Sourceconfig (base + override rows)
Effectread-only (write disabled, SPEC Rev 21)
Statepending
Agent run state

What this section is for: stop or start the agent's entire workflow. "Off" means the poller takes no new work, no Gmail is consumed, no vision spend and no PlanoQ write occurs, and in-flight work finishes its current unit before stopping. The webhook receiver keeps recording regardless -- off means the agent takes no action, not that it goes deaf. On resumption the backlog is processed, not skipped.

Agent run statei

Stopping and starting are each a deliberate second act: press once to arm, press again to confirm. A stray click, refresh or navigation cannot throw the switch.
Loading…
GET/api/run-state
PUT/api/run-state {enabled}
Sourceconfig_params (agent.run_state.enabled)
Effectthe agent's poller/extraction cycle reads this same key and refuses new work while it is false
Statepending

Change historyi

Who changed the run state, when, and to what. Newest first.
GET/api/run-state/history
Sourceaction_log (auth_agent_run_state_change)
Effectread-only; the audit row this tab's toggle already writes
Statepending

What this tab is for: every floorplan-eligible PlanoQ job as a thin line item with status and a link out. Read-only: nothing here writes to PlanoQ or the agent's own store. Click a job's issue number to open it in PlanoQ.

Issue IDAddressCard statusLifecycleUpdated
GET/api/jobs
Sourcejobs, joined with the agent-store fp_status projection
Effectrenders the real job list; PlanoQ link built client-side from issue_id, no write of any kind
Statepending

What this tab is for: one place to see everything the agent couldn't finish on its own, centralized across PlanOq and Zillow 3D. This board is read-only toward PlanOq — your team keeps working in PlanOq and the Zillow 3D dashboard exactly as today, and nothing here writes to PlanOq. Most items clear themselves once the agent sees the real status change. A tour with no address cannot: no signal will ever arrive for it, so it waits for a person.

How an item moves: Active→ a user taps Mark addressed → Marked addressed→ agent sees the real status change → Resolved · or after the configured window with no real resolution, it drops back to Active (only the agent confirms Resolved)

Issue queuei

Read-only toward PlanOq. Link out to do the actual work in PlanOq or Zillow 3D; the board updates itself when the status changes.
GET/api/escalations?view={active|addressed|resolved}
MARKPOST /api/escalations/{id}/addressed · POST /api/escalations/{id}/active — agent store ONLY (never PlanOq)
Sourcetour_items, jobs.cf70, qa_results — derived, read-only; re-derived from PlanOq saves + Zillow emails via receiver
Effectself-clears on status change; addressed auto-returns after marked_addressed_return_hours; agent sets Resolved; NO PlanOq write
Statepending

QA vieweri

Opened from any escalation or job.
GET/api/qa/{job_id}
Sourceqa_results, floorplans
Effectrenders image + per-check results
Statepending

What this tab is for: browse EVERY job's full agent result, beyond the aggregate calibration matrix and the escalations subset. Filter by agreement outcome (including the critical false-pass cell), by per-check firing, and by date window. Read-only: this table never writes, never mutates a job, and offers no approve or advance action of any kind.

Browse-all audit tablei

Rows reflect the derived, append-only source (action_log + the §5a closure tuples) exactly. Not-yet-closed rows are visible but unlabeled, never asserted resolved. Zero rows under a filter shows zero rows and the filter, never sample data. Rows deep-link to the per-job QA drill-in on the HITL tab.
GET/api/audit/orders?agreement&check&check_status&false_pass&from&to&date_field — the ONLY method under /api/audit
Sourceqa_results ⋈ qa_check_results ⋈ action_log ⋈ §5a closure tuples — derived, read-only; the closure tuple's self-label scores agreement, the run verdict governs the qa_review bar
Effectfilterable browse-all (client-side sort/page); bad filter → server 400 surfaced; ZERO writes by construction
Statepending
Phase-5 dashboard · built to Interface Contract Rev 11 (contract wins on conflict; mockup is the visual reference) Wiring state: proven by live round-trip against the backend · 0 wired · 0 dead

UI wiring ledger

0 wired · 0 dead

Every interactive element, traced element → endpoint → handler → data source → runtime effect → live round-trip state. State reflects the LAST real request, never a design-time assertion: live (data rendered), empty (endpoint returned nothing — honest empty-state), refused (server 401/403 reflected), pending (not yet exercised), not wired (the round-trip can succeed, but no code path this agent runs actually reads the key back, so editing it cannot change real behavior; ROUTING 157 audit).

ElementEndpointHandler / sourceRuntime effectState