FixThis exports one annotation model for clipboard JSON, Markdown, CLI, and MCP. The current schema version is 1.0.
Current MCP feedback-console sessions are the primary output surface. Legacy single-annotation fields remain documented for compatibility because session items map through the same core annotation model.
These fields are always present in an annotation:
schemaVersion: schema version string.id: annotation id.createdAtEpochMillis: capture time.platform: currentlyandroid-compose.app.packageName: Android application id.app.debuggable: whether the app is debuggable.activity.className: current Activity class.tap.xInWindowandtap.yInWindow: tap coordinate in window pixels.selection.kind: selection result kind.selection.confidence: selection confidence.selection.source: selection source.userComment: user-entered request text.errors: list of structured errors. Empty means no known error.
FixThis JSON is encoded with explicitNulls=false and encodeDefaults=true. Nullable optional fields are omitted when their value is null. Collections with default empty values are emitted as empty arrays.
These fields can be absent or empty depending on runtime context:
app.versionName,app.versionCodeselection.selectedUidselection.areaBoundsInWindowselectedNodecandidatesAtPointscopeCandidatesnearbyNodessourceCandidateseditSurfaceCandidatestargetEvidencetargetReliabilitysearchHintsscreenshot
targetEvidence is optional additive evidence for agent handoff. In the current MCP console flow, it is generated when Copy Prompt or Save to MCP persists written pending annotations and promotes a frozen preview into persisted feedback items. It may be absent when the captured screen, selected target, or source index does not provide enough structured evidence.
identityHint: optional target identity derived from strict test tags (comp:<ComposableName>:<variant>,screen:<ComposableName>:<id>, or dot-delimitedcomp.<ComposableName>.<id>) or stable semantics labels.occurrence: optional ordinal/count for the selected target, based on captured merged semantics nodes.sourceInterpretation: optional summary of the top source candidate, source-match reasons, and confidence caution.evidenceQuality:BASICorSTRUCTURED.screenshotKinds: screenshot artifact kinds available for the annotation, such asfullandcrop.warnings: human-readable caveats. Agents must treat these as confidence constraints.
targetReliability is optional additive metadata that tells agents how much to
trust the selected target before editing. It is not a task priority and does
not replace targetEvidence or sourceCandidates.
confidence:HIGH,MEDIUM,LOW, orUNKNOWN.reasons: machine-readable positive evidence tokens used to explain higher confidence, such asSTRICT_COMPOSABLE_IDENTITY,MEANINGFUL_COMPOSE_NODE,STRONG_SOURCE_CANDIDATE, andMEDIUM_SOURCE_CANDIDATE.warnings: machine-readable caveat tokens. Current values includeVISUAL_AREA_ONLY,NO_MEANINGFUL_COMPOSE_TARGET,POSSIBLE_VIEW_INTEROP,LOW_SOURCE_CANDIDATE_MARGIN,SOURCE_INDEX_STALE,SCREEN_FINGERPRINT_MISMATCH_FORCED,SCREEN_FINGERPRINT_UNAVAILABLE, andSENSITIVE_TEXT_REDACTED.
Agent-facing Markdown may render this confidence with action guidance. Precise
and full Markdown use sentence guidance such as inspect the source candidate
first, inspect and corroborate, treat source paths as hints only, or verify
manually. Compact Markdown preserves targetConfidence=<enum> and emits a
separate targetAction=<token> such as inspect-source-first,
inspect-and-corroborate, treat-source-paths-as-hints, or
verify-manually. These phrases and tokens are renderer output, not persisted
JSON fields.
Feedback console sessions are returned by fixthis_open_feedback_console and served by the local console API. Top-level fields:
schemaVersion: schema version string.sessionId: active feedback session id.packageName: Android application id.projectRoot: desktop project root.createdAtEpochMillis,updatedAtEpochMillis: session timestamps.screens: persisted evidence snapshots saved from frozen previews.items: feedback queue items.runtimeEvidence: additive list of bounded local runtime evidence summaries and artifact paths. It defaults to an empty list. Runtime evidence artifacts are local files and must not be committed.runtimeEvidencePolicy: persisted session policy. Values areauto_on_handoff,manual, andoff. Newly created sessions explicitly storeauto_on_handoff; legacy JSON with no field decodes asmanual.handoffBatches: persisted sent handoff batches.nextItemSequenceNumber: next monotonic human-readable feedback item number for this session. Legacy sessions that do not contain this field are migrated from the highest existing itemsequenceNumber.status:active,ready_for_agent, orclosed.
FeedbackSession.screens contains persisted evidence snapshots, not every preview frame.
Feedback session summaries are returned by fixthis_list_feedback_sessions and the feedback session index. Fields:
sessionId: persisted feedback session id.packageName: Android application id.projectRoot: desktop project root.createdAtEpochMillis,updatedAtEpochMillis: session timestamps.status:active,ready_for_agent, orclosed.screensCount: number of persisted evidence snapshots in the session.itemsCount: number of feedback items in the session.unresolvedItemsCount: number of feedback items not resolved or marked won't fix.draftItemsCount: number of feedback items whose delivery isdraft.inProgressItemsCount: number of feedback items currently claimed by an agent.sentBatchesCount: number of persisted handoff batches.
fixthis_list_feedback returns the same session context plus unresolvedSentItemsCount, the number of sent feedback items not resolved or marked won't fix.
Connection status is console-local API data returned by GET /api/connection and POST /api/app/launch. It is not persisted into FeedbackSession JSON.
Fields:
state:WELCOME,READY,OPEN_APP,STARTING,RECONNECT,CHOOSE_DEVICE,CHECK_PHONE, orUNSUPPORTED_BUILD.headline: short user-facing state label.message: user-facing recovery guidance.primaryAction: optional next action. Values areSTART,OPEN_APP,RECONNECT,TRY_AGAIN,CHOOSE_DEVICE, orCAPTURE.selectedDevice: selected device summary when available.devices: available device summaries.packageName: Android application id for the console session.canCapture: whether live capture/preview actions are currently allowed.canNavigate: whether debug navigation actions are currently allowed.canUseCachedWork: whether the console can keep saved/draft work visible while disconnected.details: optional diagnostic object withdeviceState,bridgeState, andrawError.
Device summaries include:
serial: ADB serial.state: raw ADB state, such asdevice,offline, orunauthorized.label: short display label derived from model, device name, product, or serial.selected: whether this is the active console device.
POST /api/app/launch returns the same shape. It only attempts app launch from WELCOME or OPEN_APP; CHECK_PHONE, CHOOSE_DEVICE, and UNSUPPORTED_BUILD are returned without hiding their underlying cause.
Captured screens represent persisted evidence snapshots in a feedback session. The feedback console creates them when Copy Prompt or Save to MCP persists pending annotations and promotes a frozen preview; MCP tools can also create them through explicit capture or navigation with captureAfter. Live preview frames are not captured screens:
screenId: persisted evidence snapshot id.capturedAtEpochMillis: capture timestamp.activityName: current Activity when available.displayName: console display label.screenshot: local screenshot artifact metadata when available.roots: Compose root snapshots with merged and unmerged nodes.sourceIndexAvailable: whether source matching data was available.errors: non-fatal capture or inspection errors.orientation: optional orientation string captured by the bridge.widthPx,heightPx,densityDpi: optional display metrics used for screen-integrity fingerprinting.windowMode: optional window mode such as fullscreen, split-screen, or picture-in-picture.systemUiVisible,systemUiKind: optional system UI state observed during capture.fingerprint: optional 16-character screen fingerprint derived from activity, orientation, dimensions, density, window mode, and system UI kind.
The fingerprint is additive. Legacy captures and old sidekick builds may omit it; in that case save-time mismatch checks are skipped and the feedback item can still be persisted.
Navigation results are returned by fixthis_navigate_app. Fields:
performed: whether the sidekick performed the requested action.action:back,tap, orswipe.activityName: current Activity name when available.message: optional bridge status or failure message.screen: captured screen whencaptureAfteris true and capture succeeds.captureError: capture failure message when navigation performed but follow-up capture failed.
Feedback items represent human comments on a persisted evidence snapshot. When a saved item targets a semantics node, targetEvidence is derived from that snapshot's captured merged semantics nodes and source-index candidates. Visual-area items keep occurrence unavailable and report that caveat in targetEvidence.warnings.
itemId: feedback item id.screenId: evidence snapshot saved with this item batch. Multiple items can share onescreenIdwhen they were saved together from one frozen preview.createdAtEpochMillis,updatedAtEpochMillis: item timestamps.target: selectedsemantics_nodeorvisual_area.selectedNode: selected Compose node when available.nearbyNodes: nearby context nodes.sourceCandidates: best-effort source hints.editSurfaceCandidates: optional list of likely rendering/edit surfaces for style, typography, spacing, or component-renderer feedback. Legacy sessions omit it.screenshotCrop: crop artifact metadata when available.comment: human feedback text.sequenceNumber: monotonic, stable human-readable item number within the session. Saved items are not renumbered after deletes, session switches, or MCP/console restarts.delivery:draftbefore handoff orsentafter a handoff batch records the item for agent reading.clientWorkspaceId: optional browser DraftWorkspace id that created the item. New console saves populate it so retry deduplication can survive browser/server round trips.clientDraftItemId: optional browser-local draft item id. Together withclientWorkspaceId, it forms the primary idempotency key for/api/items/batch.handoffBatchId: batch id that sent the item, present for sent items when available.sentAtEpochMillis: time the item was sent to a handoff batch, present for sent items.status:open,ready,in_progress,resolved,needs_clarification, orwont_fix.agentSummary: optional agent resolution summary.targetEvidence: optional additive evidence for stable agent handoff. When present, it follows the annotationtargetEvidenceshape above.targetReliability: optional target confidence and warning metadata. When present, it follows the annotationtargetReliabilityshape above.runtimeEvidenceIds: optional additive list of ids referencing session-levelruntimeEvidenceattachments. Items reference evidence by id so large local artifacts are not duplicated across feedback items.
ready is retained for persisted/session JSON compatibility. Domain mappers normalize legacy ready values to AnnotationStatus.OPEN; this is not a JSON field migration.
Runtime evidence attachments are optional, local-first summaries that can help
an agent verify a feedback item. Copy Prompt never starts collection.
Save to MCP runs the baseline preset only when the session policy is
auto_on_handoff; Manual and Off record a skipped attempt. A typed collection
failure does not prevent otherwise valid feedback from becoming sent.
evidenceId: stable id referenced by item-levelruntimeEvidenceIds.type:logcat_window,frame_summary,memory_summary, ortrace_artifact.capturedAtEpochMillis: local capture timestamp.deviceSerial: optional ADB serial.packageName: Android application id used for capture.timeRangeEpochMillis: optional{startEpochMillis,endEpochMillis}window.summary: bounded text summary. Raw logs and traces are not embedded in compact handoff output.artifactPath: optional local path, usually under ignored.fixthis/storage.captureCommand: optional command description used for the capture.warnings: optional warning tokens from the taxonomy below.captureId: optional id shared by all attachments created by one bounded capture. Items in one automatic same-screen handoff share this id.status:complete,partial,failed, orunsupported. Legacy manual attachments default tocomplete.trigger:handoff_auto,console_manual,mcp_manual, ormanual_attachment.screenCapturedAtEpochMillis,captureStartedAtEpochMillis, andcaptureCompletedAtEpochMillis: optional correlation timestamps.proximity: optionalnear,delayed, orstalecorrelation bucket.failureReason: optional terminal or partial failure reason.
Proximity is computed from capture start minus frozen-screen capture time:
near is 0 through 3,000 ms, delayed is more than 3,000 through 15,000 ms,
and stale is more than 15,000 ms or a negative delta. A screen-fingerprint
change downgrades near to delayed and adds context_changed.
Warning values are:
capture_deferredsensitive_logs_possibleartifact_missingoutput_truncatedredaction_appliedprocess_restartedcontext_changedstale_windowcumulative_not_windowedtimestamp_filter_unsupportedpid_filter_unsupported
Failure reasons are device_unavailable, device_changed,
package_unavailable, process_not_running, collector_unsupported,
permission_denied, capture_timeout, context_changed,
artifact_write_failed, quota_exceeded, and artifact_missing.
Device serial, install epoch, package identity/availability, session state,
item identity, and screenId are hard linkage boundaries. Drift at one of
those boundaries fails closed and does not append links. PID restart and
screen-fingerprint drift remain usable partial evidence: they add warnings and
downgrade status instead of claiming a causal match.
fixthis_collect_runtime_evidence and the additive runtimeEvidence field on
the Save to MCP response use this result shape:
attempted: whether collection was attempted.captureId: optional capture id.status: optionalcomplete,partial,failed, orunsupported.attachmentIds,linkedItemIds: bounded id lists.artifactDirectory: optional relative bundle directory.warnings: warning taxonomy above.failureReason: optional failure taxonomy above.skippedReason: optional policy/availability reason. Handoff policy usesmanualoroff.
The persisted handoff Markdown adds a runtimeEvidenceAttempt block containing
only attempted, status, a mapped failure or skip reason, and at most eight
warning tokens. It intentionally omits capture ids, attachment ids, local
paths, commands, and raw bodies.
Automatically collected artifacts use this project-relative layout:
.fixthis/runtime-evidence/<session-id>/<capture-id>/
├── logcat.txt
├── memory-summary.txt
├── frame-summary.txt
└── manifest.json
Only files produced by the selected preset are present. The file limits are
512 KiB for logcat and 128 KiB each for memory and frame summaries. One
committed bundle is capped at 2 MiB, and the project runtime-evidence root is
capped at 250 MiB under a process/JVM file lock. Commit is temporary-directory
plus atomic-rename; incomplete and orphan bundles are cleaned on recovery.
On POSIX filesystems, runtime-evidence directories are owner-only (0700) and
artifact, manifest, and quota-lock files are owner-readable/writable (0600).
Existing runtime-evidence paths are tightened when the store opens them.
Collector output is redacted before durable write. Built-in rules cover
authorization/cookie headers, FixThis tokens, common secret/key/token
assignments and query parameters, JSON secret values, and JWT-like tokens.
Authorization, cookie, and token assignment rules accept colon, equals, quoted,
JSON, and whitespace-delimited forms. Every logcat result includes
sensitive_logs_possible, even when no built-in rule reports a substitution.
The redactor accepts at most 32 optional injected patterns of at most 256
characters each and rejects unsafe regular-expression shapes. The current
console and MCP schemas do not accept redaction patterns from callers.
Persisted summaries are capped at 240 characters; compact handoff renders at
most three attachments per item and 180 summary characters per attachment.
Raw collector output is never embedded in feedback-session JSON, MCP tool
results, or handoff Markdown.
editSurfaceCandidates is an additive MCP/session-local field. It separates
source-origin evidence from likely rendering surfaces for visual, style,
typography, spacing, and component-renderer requests.
Each entry can include:
kind: one ofCONTAINER_COLOR,TEXT_COLOR,TYPOGRAPHY,SPACING,CHIP_COLOR,COMPONENT_RENDERER, orUNKNOWN.file: likely rendering/edit surface file.repoFile: optional repository-root-relative file path.line: optional line hint.confidence:HIGH,MEDIUM,LOW, orNONE.reasons: machine-readable derivation reasons, such asSTYLE_INTENT,LAYOUT_INTENT,TYPOGRAPHY_INTENT,TARGET_OWNER,SELECTED_TEXT_RENDERER,COMPONENT_DEFINITION,CALL_SITE,LIST_ITEM_SPACING, orCOMPONENT_CONTAINER.role: optional likely edit-surface role for the candidate; one ofCALL_SITE,COMPONENT_DEFINITION,COPY_OR_DATA,LAYOUT_OR_STYLE,VISUAL_AREA, orINTEROP_RISK. Absent on older persisted sessions and on candidates the classifier could not score.confidenceBasis: optional human-readable basis for the role-specific confidence.note: optional role-specific action guidance or caveat for compact handoffs. In compact Markdown, edit-surface notes render asaction:lines; source-candidate cautions still render asnote:lines.
Agents should treat these as inspection hints. They do not rename or replace
sourceCandidates, and they are absent from older persisted sessions.
The feedback console defaults to navigation. Annotate freezes the latest preview so the user can select a target or drag a visual area; that selection creates a pending UI-only item and focuses its detail editor for the comment. Pending items are numbered in the Studio UI and support focus and delete until Copy Prompt or Save to MCP persists written pending annotations when needed. That persistence promotes the frozen preview once into one persisted evidence snapshot, stores written pending items, and connects them to the same screenId. In a mixed draft, pin-only residual items stay browser-local for Copy Prompt and are discarded for Save to MCP. Later Annotate work on the same visible app screen creates a new evidence snapshot when pending annotations are persisted.
Save to MCP first resolves the session runtime-evidence policy while the
items remain draft. Auto collects and links one baseline capture for a
same-screen batch; Manual and Off skip collection. The final session is then
re-read, compact Markdown is rendered with the final evidence decision, and a
persisted handoff batch changes the items to delivery: "sent", sets
handoffBatchId and sentAtEpochMillis, and records those items in
handoffBatches. It does not create a new external AI API payload; MCP tools
read the persisted session data.
Connection loss does not change feedback delivery fields. Browser-only pending
items are mirrored separately as DraftWorkspace schema-v2 envelopes under
localStorage["fixthis.workspace.<sessionId>.<workspaceId>"], with
localStorage["fixthis.workspace.index.<sessionId>"] storing the recoverable
workspace ids for that session. Each envelope carries workspaceId,
revision, lifecycle, immutable frozen context (sessionId, previewId,
screenId, screenFingerprint, deviceSerial, frozenAtEpochMillis, and
activityName), frozen screen, screenshotUrl, browser-local items, and
undo/redo history. The persisted MCP FeedbackSession JSON remains
unchanged; workspaces are only a browser recovery mirror until written items are
persisted into .fixthis/feedback-sessions/. After Save to MCP, residual
pin-only browser recovery is cleared instead of being promoted into persisted
session JSON.
Delivery values:
draft: item is still in the current draft queue.sent: item is part of a persisted handoff batch.
Draft batch persistence is idempotent. When /api/items/batch receives
browser workspaceId and draftItemId values, persisted items retain them as
clientWorkspaceId and clientDraftItemId. Retrying the same batch does not
append duplicate items or duplicate event-log entries. If a retry contains
already-saved items plus new items from the same workspace, only the new items
are appended and they share the already-persisted evidence screen. Older items
or browser-local recovery entries without client draft ids are not semantically
deduplicated. They are unsupported pre-client-key local data and must be
discarded or recreated with current schema-v2 draft identity.
Handoff batches are stored on the feedback session in handoffBatches:
batchId: persisted batch id.sequenceNumber: stable human-readable batch number within the session.createdAtEpochMillis: time the batch was created.itemIds: feedback item ids included in the batch.markdownSnapshot: Markdown handoff snapshot captured whenSave to MCPcreated the batch, when available.
The item's screenId field points to the evidence snapshot saved with the item batch. Multiple items can share one screenId when saved together from one frozen preview.
fixthis_read_feedback returns both JSON and Markdown. JSON remains complete and preserves session, screen, item, batch, screenshot, and path fields for MCP tool contracts. Markdown is compact and agent-facing: it focuses on request, target evidence, and likely source, and intentionally omits internal IDs and repeated storage metadata.
selection.kind values:
SEMANTICS_NODE: a Compose semantics node was selected.VISUAL_AREA: the user selected a rectangle or FixThis used an area fallback.TAP_POINT: no node or area was selected; the tap coordinate is the primary signal.
selection.confidence values:
HIGH: strong semantic match, usually direct tap or scope-chip selection.MEDIUM: usable match with weaker evidence, often area selection with nearby context.LOW: weak semantic evidence.NONE: no semantic target.
selection.source values:
TAP_SELECTSCOPE_CHIPAREA_SELECTFALLBACK
sourceCandidates are best-effort ranked hints, not guaranteed file/line mappings. Each candidate can include:
file: source file candidate, preserved as generated by the source index. For Gradle modules this is module-relative.repoFile: optional repository-root-relative source path. New source indexes populate this so MCP sessions launched from the repository root can render paths agents can open directly.line: optional line from the source index.score: normalized score from0.0to1.0.matchedTerms: selected or nearby terms found in the source index.matchReasons: why the entry matched.confidence:HIGH,MEDIUM,LOW, orNONE.ranking: optional 1-based rank within the item's ordered candidate list.scoreMargin: optional score gap between this candidate and the next-ranked candidate. Populated for the rank-1 candidate; serialized into compact handoff asmargin=.evidenceStrength: optionalSTRONG,MEDIUM, orWEAKdescribing how reliable the underlying evidence is. Used to reserveconfidence=HIGHfor strong evidence with a clear top-vs-next margin.riskFlags: optional list of confidence-capping risk tokens (for exampleAREA_SELECTION,TEXT_ONLY,NEARBY_ONLY,ACTIVITY_ONLY,ARBITRARY_LITERAL,LEGACY_FALLBACK).LEGACY_FALLBACKremains the current serialized token for internal untyped-fallback source evidence. It is kept for persisted JSON and agent compatibility; it does not indicate support for pre-v0.4 browser recovery or old local artifact roots.caution: optional human-readable caveat. Surfaced on the rank-1 candidate as anote:line in compact handoff.stale: optionaltrue,false, ornull.truemeans the host source line no longer matches the index excerpt (do not edit by file:line);falsemeans the line-accurate match was verified;nullmeans the candidate could not be verified (no excerpt, no line, or an XML resource entry).staleReason: optional string explaining the staleness verdict, e.g."excerpt mismatch","file not found on host","file not found on host; sourceRoot unresolved","file not found on host; multiple suffix matches","line out of range","path escapes project root", or"file too large to verify".ownerComposable: optional simple name of the enclosing@Composable funfor the indexed source entry. Markdown handoffs render this asinside fun <name>or compactowner=<name>when present.
Generated source-index entries now include additive v2 typed signals while preserving the v1 fields (symbols, text, contentDescriptions, testTags, stringResources, roles, and activityNames). Current signal kinds are COMPOSABLE_SYMBOL, UI_TEXT, STRING_RESOURCE, STRING_RESOURCE_RESOLVED, TEST_TAG, STRICT_COMP_TEST_TAG, CONTENT_DESCRIPTION, ROLE, ACTIVITY_NAME, ARBITRARY_STRING_LITERAL, LAMBDA_OWNER_FUNCTION, and LAYOUT_RENDERER; each signal has a value and optional confidenceWeight defaulting to 1.0. STRING_RESOURCE_RESOLVED is emitted on Kotlin stringResource(R.string.name) call sites when the default-locale value is available from res/values/strings.xml; LAMBDA_OWNER_FUNCTION records the enclosing composable function for indexed Kotlin entries.
LAYOUT_RENDERER source-index signals are typed call-site evidence for Compose
Layout(...), SubcomposeLayout(...), and SubcomposeLayout { ... } usage, and
for content-slot wrapper composables — a @Composable fun exposing a
content: @Composable (...) -> Unit slot, which carries the wrapper's own
function name. Agents should interpret them with the owner composable and
confidence warnings: a layout renderer signal alone is not an exact source-line
guarantee.
Generated source indexes also include additive root metadata starting with source-index schemaVersion: "1.1". Current generated source indexes use schemaVersion: "1.2" for resolved string-resource, owner-composable, and layout-renderer signals:
sourceRoot.kind: source-root kind. Current value is"gradle-project".sourceRoot.gradlePath: Gradle project path that generated the index, such as":app".sourceRoot.projectDir: repository-root-relative Gradle project directory. Root projects use an empty string.entries[].repoFile: repository-root-relative source path for this entry.
entries[].file remains unchanged for compatibility. New MCP readers resolve candidates in this order: repoFile, sourceRoot.projectDir + file, legacy projectRoot + file, then a unique suffix fallback when exactly one host file ends with the indexed path.
Implemented match reasons include:
selected textselected contentDescriptionselected testTagselected roleselected stringResourceselected resolved stringResourcenearby textnearby contentDescriptionnearby testTagnearby roleactivity
The Android sidekick stores screenshots under the app cache directory:
context.cacheDir/fixthis/<yyyy-MM-dd>/<annotation-id>-full.png
context.cacheDir/fixthis/<yyyy-MM-dd>/<annotation-id>-crop.png
App-only clipboard exports may include Android-local fullPath and cropPath. Desktop agents cannot usually read those paths directly.
CLI and MCP flows pull screenshots through the bridge and write desktop-readable artifacts. Current persisted screen artifacts live under the feedback-session workspace and use a generated screen id:
.fixthis/feedback-sessions/<session-id>/artifacts/screens/<screen-id>/<screen-id>-full.png
.fixthis/feedback-sessions/<session-id>/artifacts/screens/<screen-id>/<screen-id>-crop.png
When available, annotation paths appear as desktopFullPath and
desktopCropPath. Feedback console screen paths appear on the screen entry.
Console preview and screen artifact HTTP URLs include the originating
sessionId; routes must resolve the artifact against that session rather than
whatever session is currently active. .fixthis/artifacts/ and
.fixthis/feedback-sessions/ are ignored by git because these files are local
debug screenshots and session metadata. If capture or storage fails,
screenshot.captureFailedReason or captureError records the failure and the
annotation or navigation result remains valid.
Errors are structured as:
{
"code": "NO_NODE_AT_TAP",
"message": "No semantics node contains the tap point",
"details": {}
}Annotation and inspection codes include current bridge/inspection failures plus legacy single-annotation capture failures:
NO_NODE_AT_TAP: no semantics node contained the tap point.SCOPE_NODE_NOT_FOUND: requested scope chip node was not found.ROOT_DISCOVERY_FAILED: Compose root discovery threw an error.SEMANTICS_MERGED_INSPECTION_FAILED: merged tree inspection failed.SEMANTICS_UNMERGED_INSPECTION_FAILED: unmerged tree inspection failed.NO_ACTIVITY: no resumed Activity is available.NO_DECOR_VIEW: current Activity has no decor view.NO_OVERLAY_CONTROLLER: legacy overlay controller is unavailable.CAPTURE_IN_FLIGHT: legacy feedback capture is already active.
Bridge and MCP failures may be returned as tool errors or JSON-RPC errors instead of annotation errors. See Troubleshooting.
Feedback-console save conflicts can also be returned as local HTTP API responses before an item is persisted:
screen_fingerprint_mismatch:POST /api/items/batchcompared the frozen preview fingerprint with a current lightweight capture and they differed. The response is HTTP 409 and includesfrozenFingerprintandcurrentFingerprint; the browser asks whether to re-capture, force-save, or cancel.
Feedback sessions are stored as a snapshot plus an append-only mutation log:
.fixthis/feedback-sessions/<session-id>/session.json
.fixthis/feedback-sessions/<session-id>/events/*.jsonl
.fixthis/feedback-sessions/<session-id>/events/checkpoint.json
.fixthis/feedback-sessions/<session-id>/events/archive/
Each event is fsync'd to a temporary file and renamed to a numbered .jsonl
file before the in-memory session is updated. On restart, FixThis replays the
active events over the snapshot. Compaction writes checkpoint.json with
schemaVersion, sessionId, compactedThroughSequenceNumber,
snapshotUpdatedAtEpochMillis, and createdAtEpochMillis, then archives the
events covered by that checkpoint. Corrupt or incompatible checkpoints are
treated as skipped replay input rather than a reason to apply archived events
twice.