Technical spec · all specs
Define and freeze the canonical request, result, evidence, coordinate, identity, and versioning contracts used by every TroveSnap Vision scan. This work establishes the language shared by:
P1 is not merely an API envelope. It defines the semantic contract for TroveSnap's progressive visual-discovery system:
Wide scene image(s)
→ candidate discovery
→ candidate selection
→ centered item identification
→ mark and condition evidence
→ appraisal readiness
→ valuation using supplied comparables
The contract must preserve what was observed, what was inferred, where the evidence came from, how certain the result is, and what scan should happen next. Changing these contracts after provider, UI, storage, and appraisal work begins would be expensive. P1 therefore defines the stable canonical model before provider-specific vision implementation starts.
Scan broadly, highlight selectively, inspect deeply, and appraise only when justified. TroveSnap Vision progressively allocates inference cost. A broad scene scan should identify a small number of promising objects rather than appraise or richly describe every visible item. More expensive analysis occurs only after an object has been isolated and additional evidence has been captured. The contract must support this staged progression without requiring every scan type to return the same payload shape.
P1 defines:
table_huntroom_scanitem_scanmark_scancondition_scanappraisal_prepareappraisal_valueP1 does not implement:
P1 may define fields required by these later systems, but it does not implement their behavior.
The canonical scan results may contain:
Vision results must not invent or own:
Those belong to TroveSnap application services and later workflows.
The seven scan types do not share a generic candidates[].fields payload.
Each result identifies its concrete schema:
result:
schema: room_scan_result
version: 3.0.0
payload:
coverage: partial
visible_instances: 44
estimated_distinct: 31
Shared primitives are reused, but each scan type has a semantically appropriate payload.
P1 defines provisional identity within a scan and across images in the same scan request. A room candidate may have multiple sightings:
candidate_id: cand_7
sightings:
- image_id: img_room_02
region:
bbox: [510, 165, 825, 770]
primary: true
- image_id: img_room_03
region:
bbox: [80, 210, 370, 790]
primary: false
P1 does not create durable item identity. E4 or the corresponding item-promotion workflow converts a provisional candidate into a persistent TroveSnap item or inventory record.
Each scan type has its own result-schema version.
A change to condition_scan_result must not force a version change to table_hunt_result.
The common request and response envelopes are also versioned independently.
P1 defines observable evidence, claims, confidence, certainty, watchlist matches, and candidate signals. P4 defines how those inputs are weighted and converted into a final deterministic candidate rank.
The contract must distinguish:
Models must not fill missing information with plausible guesses.
The contract has four independently evolving version dimensions.
Controls the common request or response wrapper:
contract:
schema: scan_request
version: 1.0.0
Controls the expected behavior of a particular scan type, including:
scan:
type: table_hunt
version: 2.0.0
Controls field names, required properties, enum meanings, and serialization for one result type:
result:
schema: table_hunt_result
version: 2.0.0
Requests and results may reference:
versions:
taxonomy: 12
watchlists:
paul_personal: 17
regional_demand: 6
condition_vocabulary: 3
appraisal_reason_vocabulary: 2
Semantic versioning applies:
Stored scan records must retain the exact versions used at execution time.
contract:
schema: scan_request
version: 1.0.0
request_id: req_8f29
tenant_id: tenant_123
scan:
type: table_hunt
version: 2.0.0
input:
images:
- id: img_table_01
role: scene
uri: signed-image-reference
width_px: 3024
height_px: 4032
orientation_applied: true
comparables: [] # required for appraisal_value; empty/omitted for other scan types
context:
sale_id: sale_221
zone_id: garage_table_1
zone_type: garage
location:
postal_code: "95682"
country: US
profiles:
watchlists:
- id: paul_personal
version: 17
- id: regional_demand
version: 6
target:
selection: scene_candidates
known_facts: {}
prior_evidence: []
options:
max_candidates: 6
include:
- watchlist_match
- potential_value
- unusual_item
Every request must include:
contract.schemacontract.versionrequest_idtenant_idscan.typescan.versionImage roles are part of the contract and must not be treated as informal labels. Initial roles include:
image_role:
- scene
- overview
- table
- shelving
- centered_item
- front
- back
- top
- side
- underside
- mark_closeup
- label_closeup
- signature_closeup
- serial_closeup
- damage_closeup
- detail
Each scan type restricts the permitted or required roles.
contract:
schema: scan_result
version: 1.0.0
request_id: req_8f29
tenant_id: tenant_123
scan:
type: table_hunt
version: 2.0.0
result:
schema: table_hunt_result
version: 2.0.0
status: completed
payload: {}
warnings: []
provenance:
taxonomy_version: 12
watchlist_versions:
paul_personal: 17
regional_demand: 6
result_status:
- completed
- completed_with_warnings
- partial
- retake_required
- insufficient_evidence
- rejected
- failed
A result with retake_required must include:
retake:
reason: multiple_center_objects
guidance: Move closer and center one item.
requested_photos:
- centered_item
Warnings must use stable reason codes:
warnings:
- code: low_visibility
message: Candidate is partially obscured.
related_candidate_id: cand_3
related_image_id: img_table_01
Messages are descriptive. Consumers must branch on code, not free-form text.
All canonical coordinates use normalized integer values.
coordinate_space:
format: xyxy
origin: top_left
range: [0, 1000]
relative_to: orientation_corrected_image
A region is represented as:
region:
image_id: img_table_01
bbox: [65, 310, 280, 690]
center: [173, 500]
Rules:
x_min < x_max.y_min < y_max.0 through 1000.center may be derived but, when supplied, must lie inside the bounding box.P1 must preserve the difference between visual evidence and interpretation.
evidence_source:
- visual_observation
- ocr
- normalized_ocr
- user_supplied
- prior_scan
- supplied_comparable
- deterministic_system
- model_inference
claim_status:
- observed
- extracted
- supplied
- normalized
- inferred
- possible
- contradicted
- unknown
claim:
field: brand
value: Pioneer
status: observed
certainty: exact
confidence: 99
evidence:
- source: ocr
image_id: img_mark_01
region:
bbox: [110, 220, 770, 510]
raw_value: PIONEER
0 through 100.unknown or be omitted according to the schema.identity_certainty:
- exact
- probable
- possible
- unknown
visibility:
- clear
- partial
- occluded
- distant
- blurred
- unknown
condition_grade:
- sealed
- like_new
- excellent
- good
- fair
- poor
- parts_only
- unknown
priority:
- low
- medium
- high
- critical
appraisal_state:
- no
- candidate
- priority
- blocked
appraisal_readiness:
- not_recommended
- candidate
- needs_item_photo
- needs_mark_photo
- needs_condition_details
- ready
- ready_with_limitations
appraisal_reason:
- visible_maker_mark
- visible_model
- visible_signature
- possible_antique
- collectible_category
- premium_material
- scarce_item
- unusual_design
- complete_set
- provenance_present
- high_value_variance
- possible_high_value
- watchlist_interest
- insufficient_identification
next_action:
- none
- isolate_item
- centered_item
- crop_item
- photograph_front
- photograph_back
- photograph_top
- photograph_sides
- photograph_underside
- photograph_maker_mark
- photograph_brand_model
- photograph_signature
- photograph_damage
- photograph_serial
- enter_dimensions
- verify_quantity
- verify_working
- request_appraisal
overlay_state:
- watchlist_match
- appraisal_candidate
- high_demand
- unusual_item
- uncertain_candidate
- scan_recommended
The UI owns presentation color, iconography, animation, and callout placement.
Watchlists are versioned request inputs, not provider-owned configuration.
watchlist:
id: paul_personal
version: 17
entries:
- id: vintage_pyrex
query: vintage patterned Pyrex bowls
aliases:
- Pyrex nesting bowls
- vintage milk-glass bowls
clues:
- printed_pattern
- nesting_set
- milk_glass
- bottom_maker_mark
priority: high
Allowed match types:
watch_match_type:
- exact
- brand_model
- maker
- visual_pattern
- attribute
- semantic
- category
A result may reference only:
A model must never invent a watchlist ID or entry ID.
Boundary (P1 ↔ E8): P1 owns the watchlist request + match I/O shape above. E8 owns the matching behavior/implementation and must consume this contract rather than redefine it. See Open Questions §21.
Scene candidates are provisional discoveries.
candidate:
id: cand_7
label: sculptural lounge chair
category: furniture.chair.lounge
confidence: 86
identity_certainty: possible
model_priority_hint: high
sightings:
- image_id: img_room_02
region:
bbox: [510, 165, 825, 770]
center: [668, 468]
visibility: clear
primary: true
watchlist_matches: []
appraisal:
state: candidate
reasons:
- unusual_design
ui:
overlay_state: appraisal_candidate
overlay_label: A
callout: Photograph chair separately
selectable: true
next_scan:
type: item_scan
version: 2.0.0
reason: candidate_requires_isolation
requested_photos:
- centered_item
Rules:
model_priority_hint is a provider/model hint only; P4 owns authoritative rank, final score, and priority band.Any scan may recommend a follow-up scan where appropriate.
next_scan:
type: mark_scan
version: 1.0.0
reason: exact_model_unconfirmed
requested_photos:
- photograph_brand_model
- photograph_serial
target:
parent_candidate_id: cand_7
A next-scan directive is a recommendation, not proof that the next scan has been scheduled or completed.
table_hunt_resultPurpose — Find a limited number of items in a single crowded scene that deserve separate scanning.
Required payload fields
payload:
image_id: img_table_01
visible_items_estimate: 24
candidates: []
Each candidate must include:
Invariants
room_scan_resultPurpose — Analyze multiple images of one physical zone, estimate visible and distinct objects, categorize the space, and identify promising candidates.
Required payload fields
payload:
coverage: partial
visible_instances: 44
estimated_distinct: 31
categories:
- category: furniture
count: 8
tags: [sofa, chair, table, cabinet]
candidates: []
missing_coverage:
- cabinet_interior
- rear_shelf
Invariants
item_scan_resultPurpose — Identify and summarize the primary centered object.
Success shape
payload:
status: identified
item:
category: electronics.audio.receiver
name: Pioneer SX-series stereo receiver
identity:
certainty: probable
confidence: 91
summary: >
Silver-face stereo receiver with an analog tuning display,
wood cabinet, and visible wear along the upper cabinet edge.
Pioneer branding is visible. The exact model should be
confirmed from the rear label.
visual_attributes:
colors: [silver, brown]
materials: [metal, wood_or_veneer]
features:
- analog_tuning_dial
- wood_case
- front_control_knobs
visible_condition:
grade: fair
issues:
- cabinet_edge_wear
- surface_dust
claims: []
tags:
- stereo_receiver
- vintage_audio
- analog_tuner
- silver_face
- wood_case
appraisal:
state: candidate
reasons:
- visible_maker_mark
- high_value_variance
next_scan:
type: mark_scan
version: 1.0.0
requested_photos:
- photograph_brand_model
- photograph_serial
Retake shape
result:
status: retake_required
retake:
reason: multiple_center_objects
guidance: Move closer and center one item.
requested_photos:
- centered_item
Invariants
retake_required when targeting is unreliable.mark_scan_resultPurpose — Extract and normalize a mark, label, signature, maker, model, serial number, or visible date.
Payload
payload:
status: readable
mark_type: manufacturer_label
raw_text:
- PIONEER
- STEREO RECEIVER
- MODEL SX-780
- SERIAL NO. ZF3602189
normalized:
brand: Pioneer
model: SX-780
serial: ZF3602189
uncertain_characters: []
confidence: 99
claims: []
Invariants
condition_scan_resultPurpose — Record visible condition, defects, damage, and apparently missing parts across one or more images of the same item.
Payload
payload:
grade: fair
observations:
- area: cabinet_top
issue: finish_wear
severity: moderate
evidence:
- image_id: img_condition_top
- area: cabinet_edge
issue: veneer_chip
severity: minor
evidence:
- image_id: img_condition_damage
apparently_missing_parts: []
functional_status: unknown
confidence: 92
Invariants
unknown unless supplied as a known fact.appraisal_prepare_resultPurpose — Determine whether sufficient evidence exists for valuation and create a normalized comparable-search fingerprint.
Payload
payload:
readiness: ready_with_limitations
identification:
brand: Pioneer
model: SX-780
confidence: 98
sufficient:
- model_identification
- front_condition
- cabinet_condition
- rear_label
- location
missing:
- audio_channel_test
- service_history
- interior_condition
conflicts: []
search_fingerprint:
query: Pioneer SX-780 stereo receiver powers on cosmetic wear
category: vintage_audio_receiver
region: "95682"
appraisal_confidence_ceiling: medium
next_scan:
type: condition_scan
version: 1.0.0
reason: additional_condition_evidence_would_improve_valuation
Invariants
appraisal_value_resultPurpose — Synthesize value ranges and adjustments from normalized item evidence and supplied comparable records.
Payload
payload:
currency: USD
estimates:
quick_sale: [225, 285]
normal_estate_sale: [285, 375]
patient_local_sale: [350, 450]
recommended_starting_price: 395
confidence: medium
adjustments:
- factor: powers_on
effect: positive
- factor: audio_untested
effect: negative
- factor: cabinet_wear
effect: negative
- factor: recognized_model
effect: positive
strongest_comps:
- tc_102
- tc_101
- ext_201
missing_evidence:
- audio_channel_test
- service_history
limitations: []
Invariants
Results reference a versioned hierarchical taxonomy. Initial root categories include:
category_root:
- furniture
- art
- decor
- kitchen
- appliances
- electronics
- tools
- garden
- clothing
- jewelry
- collectibles
- books_media
- toys_games
- sports_outdoor
- musical
- automotive
- office
- miscellaneous
Example paths:
category_examples:
- furniture.table.dining
- furniture.table.side
- furniture.chair.arm
- furniture.chair.lounge
- kitchen.cookware.cast_iron
- kitchen.glassware.mixing_bowl
- electronics.audio.receiver
- collectibles.ceramic
- art.painting
P1 defines how taxonomy IDs are referenced and versioned. Taxonomy curation is maintained in a separate work item (WI-057, Backlog).
P1 is complete only when the repository contains:
The implementation language may generate types from JSON Schema, but JSON Schema is the canonical interchange definition.
P1 is schema- and contract-focused. It does not require a live model or provider.
For each scan type:
The contract test suite must verify:
table_hunt cannot return valuation fields.retake_required.scan.type and behavior version echo the request.Room-scan fixtures must cover:
P1 is complete when:
fields object.0–1000 coordinates are fully specified and tested.appraisal_prepare and appraisal_value remain separate contracts.appraisal_prepare cannot return a valuation.appraisal_value cannot cite unsupplied comparables.P1 is done when the schema package, shared vocabulary, fixtures, and contract tests are merged and can be consumed by P2, P3, P4, UI, storage, and appraisal work without requiring those teams to invent missing semantic fields. A live provider call is not required for P1 completion. P2 will prove that at least one real provider can populate these contracts. P3 will prove that invalid provider responses can be detected, retried, repaired, or rejected. P4 will define deterministic candidate ranking from the canonical evidence and signals. The outcome of P1 is a stable, provider-independent visual evidence and scan-orchestration language, not merely a request/response DTO.
Resolved for the WI-010 freeze:
appraisal_value comparables input - resolved. The value scan uses a dedicated input.comparables[] channel. It is required for appraisal_value, and appraisal_value_result.strongest_comps[] may reference only supplied comparable IDs.next_scan.target.parent_candidate_id remain provisional caller-carried lineage until P10 defines scan-session identity and orchestration.P8-observability-cost.md Sections 8.3, 10, 41, 61.priority -> model_priority_hint - resolved. P1 uses model_priority_hint; it is a provider/model hint only. P4 computes the authoritative priority_band, final_score, and rank.