---
name: property-assessor
description: Assess a real property from an address or listing URL and produce a decision-grade summary. Use when a user wants fair value, comps, rental or STR viability, carry-cost review, HOA or insurance risk analysis, or offer guidance for a condo, house, townhouse, or similar residential property. Prefer when the task should discover and reconcile multiple listing sources from a street address first, then give a buy/pass/only-below-X verdict.
---

# Property Assessor

Start from the property address when possible. Treat listing URLs as supporting evidence, not the only source of truth.

## Inputs

Accept any of:
- a street address
- one or more listing URLs
- an address plus the reason for the assessment, such as investment property, vacation home, owner-occupant, long-term rental, STR, or housing for a child in college

The assessment purpose is required for a decision-grade result.
If the user does not say why they want the property assessed, stop and ask before finalizing the analysis.
Do not silently infer or reuse the assessment purpose from earlier turns just because the property address is the same.
Only reuse a prior purpose when the user explicitly says it is the same purpose as before.
If the current request includes only the property/address plus email or PDF instructions, treat the assessment purpose as missing and ask again.
If the current request explicitly says to email or send the PDF to a stated target address, treat that as delivery authorization for that target once the report is ready. Do not ask for a second "send it" confirmation unless the user expressed uncertainty or changed the destination.

If the property has a unit / apartment / suite number, include it.
Do not drop the unit when discovering listing sources. Unit-qualified condo/townhome addresses must be matched as the exact unit, while single-family addresses with no unit should still work normally.

## Core workflow

1. Normalize the address and property type.
2. Discover accessible listing or public-record sources for the same property.
3. Establish a baseline fact set from the best available source.
4. Cross-check the same property on other sites.
5. Pull same-building comps for condos or nearby comps for houses/townhomes.
6. Underwrite carrying cost with taxes, HOA, insurance, and realistic friction.
7. Flag risk drivers before giving a verdict.
8. End with a specific recommendation: `buy`, `pass`, or `only below X`.

Completion rule:
- A preliminary helper payload is not completion.
- If `assess` returns a preliminary payload, continue the remaining analysis yourself in the same run.
- Use the preliminary payload as scaffolding for the missing work: listing facts, comp analysis, valuation range, condition interpretation from photos, and final verdict.
- Do not stop and ask the user whether to continue just because the helper stopped at a preliminary checkpoint.
- Only interrupt the user when there is a genuine blocker: missing assessment purpose, missing recipient email at final render/send time, unavailable listing/public-record sources with no reasonable fallback, or missing facts that cannot be recovered.

## Approval-averse / chat-safe behavior

When operating from chat surfaces such as WhatsApp, Telegram, Signal, or other messaging channels, prefer workflows that do **not** trigger host exec approval prompts.

Use this priority order:
1. `web-automation` for Zillow/HAR listing discovery, rendered listing facts, all-photos flows, and other anti-bot-heavy property pages
2. `web_fetch` when an official CAD/assessor page or simple listing/public page is directly fetchable
3. `web_search` only as a narrow fallback to discover an alternate URL after direct `web-automation` / `web_fetch` attempts miss
4. interactive browser/gallery automation only as a last resort

Rules:
- Prefer accessible listing text, public mirrors, and scrollable all-photos pages over custom gallery traversal.
- Avoid fragile interactive gallery flows if they are likely to require approval or bounce the user into Control UI.
- If a richer photo pass would require approval, do not silently force that path first. Continue with the best approval-free workflow available and clearly lower confidence if needed.
- Only escalate to approval-heavy browser interaction when there is no reasonable alternative and the extra fidelity materially changes the assessment.
- In WhatsApp or similar messaging runs, keep the core assessment on `web-automation` plus `web_fetch`. Treat `web_search` as a fallback discovery aid, not the primary property-analysis path.
- For Zillow/HAR property discovery, photo extraction, and rendered listing review, do **not** start with Brave-backed `web_search` when `web-automation` can open the candidate source directly.
- For CAD/public-record enrichment, prefer official assessor/CAD pages via `web_fetch` first. Use `web-automation` when the official site needs rendered interaction. Do **not** start CAD lookup from generic web-search snippets when the official site is already known or derivable from the address.
- In Texas runs, do **not** use `https://www.texas.gov/propertytaxes/search/` as the CAD lookup path. Use the address-first CAD/helper path or the discovered county CAD pages directly.
- In those messaging runs, do **not** make `scripts/property-assessor assess`, `scripts/property-assessor locate-public-records`, `node zillow-discover.js`, `node har-discover.js`, `node zillow-photos.js`, `node har-photos.js`, `curl`, or `wget` the default core-analysis path.
- From messaging runs, the only subprocess-style step you should attempt by default is the final `scripts/property-assessor render-report` call after the verdict, fair-value range, and report body are complete.
- Do **not** inspect Gmail/email-send skills, mail tooling, or delivery integrations until the assessment is complete and the PDF is either already rendered or ready to render immediately.
- Property-assessor delivery emails should be sent as Luke from Luke's Google Workspace account, while still delivering to the user-specified destination.
- Use `zsh ~/.openclaw/workspace/bin/gog-luke gmail send --to "<target>" --subject "<subject>" --body "<body>" --attach "<pdf-path>"` for the final PDF delivery step.
- Do **not** use generic `gog` or the Stefano helper `node ~/.openclaw/workspace/integrations/google-workspace/gw.js` for property-assessor report delivery.
- If you need to confirm Luke auth before sending, use `zsh ~/.openclaw/workspace/bin/gog-luke auth list --check --plain`.
- A silent helper is a failed helper in messaging runs. If a background helper produces no useful stdout/stderr and no result within a short bound, stop polling it, treat that path as failed, and continue on the chat-native assessment path instead of narrating that it is still chewing.
- If Zillow photo extraction fails, immediately continue with HAR photo fallback or the next available rendered listing/photo source. Do **not** stop the assessment because one Zillow photo subprocess failed.
- After a Zillow/HAR photo miss, continue the comp and CAD/public-record work in the same run. A photo-source miss is a fallback event, not a terminal state.
- Do **not** leave the user parked behind background helper polling. If a helper has not produced a result quickly, give a concise status update and continue the assessment with the next available non-helper path.
- If the user already instructed you to email/send the finished PDF to a specific target, do **not** ask for a second send confirmation after rendering. Render, send, and report the result.
- If the final PDF render fails, return the complete decision-grade report in chat and say the render/send step failed. Do not restart the whole assessment.
- Do **not** run `npm install`, `npm ci`, or other dependency-setup commands during a normal chat assessment flow when the local skill already has `node_modules` present.
- On this machine, treat `property-assessor` dependencies as already installed. Use the helper entrypoints directly unless the wrapper itself explicitly reports missing local dependencies.
- Do **not** use ad hoc shell snippets, heredocs, or inline interpreter eval for public-record or CAD lookup from chat. Avoid forms like `python3 - <<'PY'`, `python -c`, `node -e`, `node --input-type=module -e`, or raw `bash -lc '...'` probes.
- For public-record enrichment in chat, prefer `web_fetch` plus official assessor/CAD pages. If a one-off helper is truly needed, add a file-based helper under the skill tree first and use it from a non-messaging surface instead of inline code.

## Source order

Prefer this order unless the user says otherwise:
1. Zillow
2. Redfin
3. Realtor.com
4. HAR / Homes.com / brokerage mirror pages
5. county or appraisal pages

Use the `web-automation` skill for rendered pages and anti-bot-heavy sites.
Use `web_search` sparingly to discover alternate URLs, then return to `web-automation` for extraction.

## Helper runtime

These helper commands are primarily for local/manual runs, non-chat surfaces, and the final PDF render step. They are **not** the default WhatsApp core-analysis path.

`property-assessor` now includes TypeScript helper commands for:
- address-first preliminary assessment assembly
- public-record jurisdiction lookup
- fixed-template PDF rendering

Before using those helper commands:

```bash
cd ~/.openclaw/workspace/skills/property-assessor
test -x node_modules/.bin/tsx
```

Quick command summary:

```bash
cd ~/.openclaw/workspace/skills/property-assessor
scripts/property-assessor assess --address "<street-address>"
scripts/property-assessor assess --address "<street-address>" --assessment-purpose "<purpose>"
scripts/property-assessor assess --address "<street-address>" --assessment-purpose "<purpose>" --recipient-email "<target@example.com>"
scripts/property-assessor locate-public-records --address "<street-address>"
scripts/property-assessor render-report --input "<report-payload-json>" --output "<output-pdf>"
```

`assess` is the address-first entrypoint for helper-driven runs. It should:
- require the assessment purpose
- treat the assessment purpose as missing unless it is present in the current request or explicitly confirmed as unchanged from earlier context
- resolve official public-record jurisdiction automatically from the address
- keep CAD discovery jurisdiction-specific from the address; do not hardcode one county CAD for every property
- try to discover Zillow and HAR listing URLs from the address when no listing URL is provided
- start Zillow and HAR discovery in parallel, while still preferring Zillow first for the photo-review path
- run the approval-safe Zillow/HAR photo extractor chain automatically
- allow slower exact-unit Zillow pages a longer source-specific discovery/photo window before giving up and falling back
- build a purpose-aware report payload
- complete the analysis without requiring recipient email(s)
- only stop and ask for recipient email(s) when the user is explicitly rendering or sending the PDF
- render the PDF only after recipient email(s) are known
- do **not** render or send a PDF from the helper's preliminary payload while verdict is still `pending` or fair value is not established
- do **not** render or send a decision-grade PDF while `photoReview.status` is anything other than `completed`
- if comps, valuation, or decision-grade condition interpretation are still incomplete, return the preliminary payload and say that the PDF/send step must wait

Agent follow-through rule:
- When the user asked for a full property assessment or asked for the PDF/email result, do not stop at the helper output.
- After `assess` returns a preliminary payload, continue with the remaining manual/model-driven steps needed to reach a decision-grade report.
- Only after the verdict and fair-value range are established should you render/send the PDF.
- A verdict and fair-value range are still not enough by themselves; the subject-unit photo review must also be completed before the PDF/send step.
- If the analysis still cannot be completed, explain the first real blocker, not just that the helper was preliminary.
- If the user sends `update?`, `and?`, or similar mid-run, answer with status and keep the original assessment going. Do not treat that message as a reset or a cue to stop at the last helper checkpoint.
- In WhatsApp or similar messaging runs, do **not** start a background `assess` helper and then wait on repeated zero-output polls. That counts as a failed path; abandon it and continue with native search/fetch/browser work.
- In WhatsApp or similar messaging runs, do **not** start mail-sending or mail-skill discovery before the report content, verdict, and delivery artifact are ready.
- Once the report is ready, treat an explicit prior instruction like "Email pdf version to me at <address>" as sufficient authorization to send.

## Public-record enrichment

Public-record / assessor data should be used when available and linked in the final result.

Default approach:
1. start from the street address
2. resolve the address to county/state/geography
3. identify the related appraisal district / assessor jurisdiction
4. use the official public-record site as a primary-source check against listing data
5. link the official jurisdiction page and any direct property page used in the final result

Approval-safe rule:
- do not perform CAD/public-record discovery with inline shell or interpreter snippets
- in chat/messaging runs, prefer `web_fetch` plus official CAD/assessor pages first
- use the built-in TypeScript helper path on local/manual surfaces or for the final PDF render step
- if rendered interaction is unavoidable, use bounded `web-automation` behavior rather than ad hoc shell text

Use the helper CLI first on local/manual surfaces:

```bash
cd ~/.openclaw/workspace/skills/property-assessor
scripts/property-assessor locate-public-records --address "<street-address>"
```

When you want the helper to assemble the preliminary assessment payload in one step from a non-messaging surface, use:

```bash
cd ~/.openclaw/workspace/skills/property-assessor
scripts/property-assessor assess --address "<street-address>"
```

This command should automatically include the public-record jurisdiction result in the returned assessment payload.
When `--assessment-purpose` is present, it should also:
- frame the analysis around that stated purpose
- try Zillow discovery from the address
- try HAR discovery from the address
- run Zillow photo extraction first when available, then HAR as fallback
- include the extracted `imageUrls` in `photoReview` when successful

This command currently:
- resolves the address through the official Census geocoder
- when Census address matching misses, falls back to an external address geocoder and then resolves official Census geographies from coordinates
- retries the fallback geocoder without the unit suffix when a condo/unit-qualified address is too specific for the fallback provider
- returns county/state/FIPS/GEOID context
- for Texas, resolves the official Texas Comptroller county directory page
- returns the county appraisal district and tax assessor/collector links when available
- when a supported official CAD detail host is found, retrieves subject-property facts from that county CAD and includes them in the assessment payload

Important rules:
- listing-site geo IDs are hints only; do **not** treat them as assessor record keys
- parcel/APN/account identifiers from Zillow/HAR/Redfin are much stronger keys than listing geo IDs
- if Zillow exposes a parcel/APN/account number on the listing, capture it and feed that identifier into CAD lookup before relying on address-only matching
- if a direct public-record property page is available, use its data in the assessment and link it explicitly
- when the helper exposes official CAD owner, legal-description, property-ID/account, value, or exemption data, treat those as primary-source facts in the model's assessment
- if the jurisdiction can be identified but the property detail page is not directly retrievable, still link the official jurisdiction page and say what could not be confirmed
- a host approval prompt triggered by an ad hoc shell snippet is workflow drift; return to `locate-public-records`, `assess`, `web_fetch`, or a file-based helper instead of approving the inline probe by default

### Texas rule

For Texas properties, public-record enrichment is required when feasible.

Process:
1. run `locate-public-records` from the subject address
2. use the returned Texas Comptroller county directory page as the official jurisdiction reference
3. use the returned CAD website for address / account / parcel lookup
   - when Zillow exposes the parcel/APN/account number, prefer that over address-only search
4. when accessible, capture:
   - account number
   - owner name
   - land value
   - improvement value
   - assessed total
   - exemptions
   - tax office links

In the final assessment, explicitly label official public-record facts as such.

Nueces-specific note:
- when searching Nueces CAD by parcel / Geographic ID, format the identifier with a dash after the first 4 digits and after the first 8 digits, for example `123456789012` -> `1234-5678-9012`

## Minimum data to capture

For the target property, capture when available:
- address
- ask price or last known list price
- property type
- beds / baths
- sqft
- lot size if relevant
- year built
- HOA fee and included services
- taxes
- days on market
- price history
- parking
- waterfront / flood clues
- subdivision / building name when applicable
- same-building or nearby active inventory
- listing photos and visible condition cues
- included appliances and obvious missing appliances
- flooring mix, especially whether carpet is present
- public-record jurisdiction and linked official source
- account / parcel / tax ID if confirmed
- official assessed values and exemptions if confirmed

## Photo and condition review

Always look at the listing photos when they are available. Do not rate a property only from structured text.

### Required photo-access workflow

When the source site exposes listing photos, prefer the **most accessible all-photos view** first. This can be:
- a scrollable all-photos page
- a photo grid
- an expanded photo list
- or, if necessary, a modal gallery/lightbox

Use `web-automation` for this. Preferred process:
1. Open the listing page.
2. Click the photo entry point such as `See all photos`, `See all 29 photos`, `Show all photos`, or the main hero image.
3. If that opens a scrollable all-photos view, grid, or photo page that clearly exposes the listing images, use that directly for photo review.
4. Only use next-arrow / slideshow traversal when the site does not provide an accessible all-photos view.
5. If you must use a modal/lightbox, verify that you are seeing distinct images, not just a gallery preview tile or repeated screenshot of the first image.
6. Review enough images to cover the key rooms and exterior, and for smaller listings aim to review all photos when practical.
7. If photo access fails or is incomplete, say so explicitly and do not claim that you reviewed all photos.

Minimum honesty rule: never say you "looked at all photos" unless the site actually exposed the full set and you successfully reviewed them.
A gallery landing page, collage preview, repeated first image, or a single screenshot of the listing page does **not** count as full photo review.

### What to inspect in the photos

At minimum, note:
- overall finish level: dated, average, lightly updated, fully updated
- kitchen condition: cabinets, counters, backsplash, appliance quality
- bathroom condition: vanity, tile, surrounds, fixtures
- flooring: tile, vinyl, laminate, hardwood, carpet
- whether carpet appears in bedrooms, stairs, or living areas
- obvious make-ready issues: paint, damaged trim, old fixtures, mismatched finishes, worn surfaces
- visible missing items: refrigerator, washer/dryer, range hood, dishwasher, etc.
- any signs of deferred maintenance or water intrusion visible in photos
- exterior/common-area condition when visible
- balconies, decks, sliders, windows, and waterfront-facing elements for condos/townhomes near water

### If photo review is incomplete

If photos are weak, incomplete, blocked, or the gallery automation fails:
- say so explicitly
- lower confidence
- avoid strong condition claims
- do not infer turnkey condition from marketing text alone

### Mandatory photo-review rule

If an accessible all-photos view, photo grid, photo page, or fallback source exists, photo review is **required** before making condition claims.
Do not silently skip photos just because pricing, comps, or carrying-cost analysis can proceed without them.

Before outputting `Photo review: not completed`, you must attempt a reasonable photo-access chain when sources are available.
Preferred order:
1. primary listing source all-photos page (for example Zillow `See all photos` / `See all X photos`)
2. HAR photo page
3. Realtor.com photo page
4. brokerage mirror or other accessible listing mirror

Use the first source that exposes the listing photos reliably. A scrollable photo page, photo grid, or expanded all-photos view counts.
Do not stop at the first failure if another accessible source is available.

### Zillow-specific rule

For Zillow listings, do **not** treat the listing shell text or hero gallery preview as a photo review attempt.
You must use **only `web-automation`** to:
1. open the Zillow listing page
2. click `See all photos` / `See all X photos`
3. access the resulting all-photos page or scrollable photo view
4. review the exposed photo set from that page

If Zillow exposes a page with a scroller that shows the listing photos, that page counts as the Zillow photo source and should be used directly.
If that scroller page exposes direct image links such as `https://photos.zillowstatic.com/...`, treat those URLs as successful photo access and use that image set for review.
This is preferred over fragile modal next/previous navigation.
If the rendered Zillow listing shell itself already exposes the full direct Zillow image set and the extracted image count matches the announced photo count, that also counts as successful photo access even if the `See all photos` click path is flaky.

For this normal Zillow all-photos workflow, stay inside **`web-automation` only**.
Use the dedicated file-based extractor first:

```bash
cd ~/.openclaw/workspace/skills/web-automation/scripts
node zillow-photos.js "<zillow-listing-url>"
```

Do **not** escalate to coding-agent, ad hoc Python helpers, or extra dependency-heavy tooling just to open `See all photos`, inspect the scroller page, or extract Zillow image URLs.
Only escalate beyond `web-automation` if `web-automation` itself truly cannot access the all-photos/scroller page or the exposed image set.

Do not rely on generic page text, photo counts, or non-photo shells as a Zillow attempt.
Only fall back to HAR/Realtor/broker mirrors if the Zillow all-photos path was actually attempted with `web-automation` and did not expose the photos reliably.
A source only counts as an attempted photo source if you actually did one of these:
- opened the all-photos page / photo grid / photo page successfully, or
- explicitly tried to open it and observed a concrete failure

The following do **not** count as a photo-source attempt by themselves:
- seeing a `See all photos` button
- seeing a photo count
- reading listing text that mentions photos
- capturing only the listing shell, hero image, or collage preview

### HAR fallback rule

If Zillow photo extraction does not expose usable direct image URLs, try HAR next for the same property.

For HAR listings, use **only `web-automation`** to:
1. open the HAR listing page
2. click `Show all photos` / `View all photos`
3. access the resulting all-photos page or photo view
4. extract the direct image URLs from that page

Use the dedicated HAR extractor first:

```bash
cd ~/.openclaw/workspace/skills/web-automation/scripts
node har-photos.js "<har-listing-url>"
```

If HAR exposes the direct photo URLs from the all-photos page, treat that as successful photo access and use that image set for review.
Do not stop after a failed Zillow attempt if HAR is available and exposes the listing photos more reliably.

When a dedicated extractor returns `imageUrls`, inspect the images in that returned set before making condition claims.
For smaller listings, review the full extracted set when practical; for a 20-30 photo listing, that usually means all photos.

### Approval-safe command shape

When running `web-automation` from chat-driven property assessment, prefer file-based commands under `~/.openclaw/workspace/skills/web-automation/scripts`.

Good:
- `node check-install.js`
- `node zillow-photos.js "<url>"`
- `node har-photos.js "<url>"`

Avoid approval-sensitive inline interpreter eval where possible:
- `node -e "..."`
- `node --input-type=module -e "..."`

The final assessment must explicitly include these lines in the output:
- `Photo source attempts: <action-based summary>`
- `Photo review: completed via <source>`
  or `Photo review: not completed`

If completed, briefly summarize the condition read from the photos.
If not completed, mark condition confidence as limited and say why.

## PDF report requirement

The deliverable is not just chat text. A fixed-template PDF report must be generated for completed assessments.

Use the property-assessor helper CLI:

```bash
cd ~/.openclaw/workspace/skills/property-assessor
npm install
scripts/property-assessor assess --address "<street-address>" --recipient-email "<target@example.com>"
scripts/property-assessor render-report --input "<report-payload-json>" --output "<output-pdf>"
```

The renderer uses a fixed template and must keep the same look across runs.
Template rules are documented in `references/report-template.md`.

The PDF report should include:
1. report header
2. verdict panel
3. subject-property summary table
4. Snapshot
5. What I like
6. What I do not like
7. Comp view
8. Underwriting / carry view
9. Risks and diligence items
10. Photo review
11. Public records
12. Source links

### Recipient-email gate

Before rendering or sending the PDF, the skill must know the target recipient email address(es).

This gate applies to the PDF step, not the analysis step.
Do not interrupt a normal assessment run just because recipient email is missing if the user has not yet asked to render or send the PDF.

If the prompt does **not** include target email(s):
- stop
- ask the user for the target email address(es)
- do **not** render or send the final PDF yet

If target email(s) are present:
- include them in the report payload
- render the PDF with the fixed template
- if a delivery workflow is available, use those same target email(s) for sending

The renderer enforces this gate and will fail if the payload has no recipient email list.

## Normalization / make-ready adjustment

Estimate a rough make-ready budget when condition is not turnkey. The goal is not contractor precision; the goal is apples-to-apples comparison.

Use simple buckets and state them as rough ranges:
- light make-ready: paint, fixtures, minor hardware, patching
- medium make-ready: flooring replacement in some rooms, appliance replacement, bathroom refresh
- heavy make-ready: major kitchen/bath work, widespread flooring, obvious deferred maintenance

Call out carpet separately. If carpet is present, estimate replacement or removal cost as part of the make-ready note.

## Underwriting rules

Always show a simple carrying-cost view with at least:
- principal and interest if available from the listing
- taxes per month
- HOA per month if applicable
- insurance estimate or note uncertainty
- realistic effective carry range after maintenance, vacancy, and property-specific risk

Treat these as strong caution flags:
- high HOA relative to price or expected rent
- older waterfront or coastal exposure
- unknown reserve / assessment history for condos
- many active units in the same building or micro-area
- stale days on market with weak price action
- no clear rent support

## Output format

Keep the answer concise but decision-grade:

1. Snapshot
2. What I like
3. What I do not like
4. Comp view
5. Underwriting / carry view
6. Risks and diligence items
7. Verdict with fair value range and offer guidance

Also include:
- public-record / CAD evidence and links when available
- the path to the rendered PDF after generation

If the user did not provide recipient email(s), ask for them instead of finalizing the PDF workflow.

## Reuse notes

When condos are involved, same-building comps and HOA economics usually matter more than neighborhood averages.
For detailed heuristics and the reusable memo template, read:
- `references/underwriting-rules.md`
- `references/report-template.md`
