# SailScan data flow — reviewed inventory

Recovered 8899786 inventory; targeted source audit 2026-09-30. Inherited edges are inferred, not proof of callers or deployment.

Unknown caller ≠ legacy. No route is proven dead by a literal-path scan. This is source analysis, not a production traffic audit.

Nodes: 371. Edges: 798.

## Nodes

| Tier | Node | Source | Notes |
|---|---|---|---|
| main | Mobile app (Expo iOS/Android) | src/api.ts:1 | ONE mobile client. Camera → prepareUploadJpeg → POST /api/analyze + POST /api/photos; renders server response verbatim (src/parse.ts). |
| main | Labeler label.sailscanapp.com | labeler/web/src/lib | Vite/React SPA, CF Pages sailscan-label. Review, Fix External, QC stages, model preview, ratings, spinnaker, boom blitz. |
| main | Desktop / team web app | desktop/src/lib/api.ts:1 | Customer/team React app; consumes server metrics verbatim; CSV/PDF/zip exports; magic upload links. |
| side | Marketing site sailscanapp.com | site/index.html:1 | Static CF Pages project sailscanapp. No /api calls found by literal-path scan. |
| side | Static galleries (CF Pages) | — | sam3-refine-gallery, sam3-guard-gallery, ruler-audit-gallery, sam3-gallery, sam-edges, workbench (own Worker+D1). Built offline from eval outputs; not part of this repo’s runtime. matrix-notes gallery → /api/matrix-notes on boats-STAGING (per memory; literal caller not in repo). |
| side | sailscan-blind-rating page | server/blindRatings.js:1 | Static page calling /api/blind-ratings with shared key (page source not in repo; caller only unblind script). |
| main | Device AsyncStorage + documentDirectory/scans/ | src/store.ts:1 | History, images, instrumentData persisted locally; background upload queue. |
| main | Railway boats (Express) | server/index.js:1 | boats-production.up.railway.app; also boats-STAGING env. |
| main | Inference sidecar (INFERENCE_URL) | server/inference/app.py:1 | FastAPI + Ultralytics. Own Railway service. Weights from R2 models/ (MODEL_R2_KEY default models/sailscan-v1.pt). |
| side | Preview sidecar (PREVIEW_INFERENCE_URL) | server/index.js:116 | Same app.py with PREVIEW_MODELS registry (deep20, yolo26, …). Used by /api/model-preview, /api/model-ranking, sam3Live finder. |
| main | RunPod SAM3 sync serverless (SAM3_SYNC_ENDPOINT_ID) | server/sam3ServerlessSync.js:77 | SAM3 refine-lines + predict. /run → /status poll. RUNPOD_API_KEY (lives on Railway). |
| side | RunPod SAM3 verify serverless (SAM3_SERVERLESS_ENDPOINT_ID) | server/sam3Verify.js:56 | Async post-scan verification; writes scan_verifications. Dormant unless env set. |
| legacy | SAM3 direct URL / pod (sam3Url, SAM3 pod manager) | server/sam3Live.js:77 | fetchSam3Predict baseUrl path used by legacy runCv refineWithSam3; dispatches to sync serverless when configured. |
| side | Cloudflare Pages (sailscan-label, sailscanapp, galleries) | — | Hosts labeler, marketing site, desktop, galleries. Static only. |
| side | North Sails API (app.northsails.com) | ~/Projects/sail-scraper/harvest-api.mjs | Harvest ONLY on Nate command. Outside this repo. |
| main | R2 images/ | server/labelStore.js:195 | sailscan-labels bucket (CF REST API, IP-restricted to Railway). Raw photos + .clean foot-down copies |
| main | R2 labels/ | server/labelStore.js:855 | sailscan-labels bucket (CF REST API, IP-restricted to Railway). Label records (points = truth, metrics derived) |
| main | R2 overlays/ | server/labelStore.js:926 | sailscan-labels bucket (CF REST API, IP-restricted to Railway). Burned-in overlay JPEGs |
| main | R2 thumbs/ | server/labelStore.js:385 | sailscan-labels bucket (CF REST API, IP-restricted to Railway). Thumbnails |
| side | R2 predictions/ | server/labelStore.js:968 | sailscan-labels bucket (CF REST API, IP-restricted to Railway). Cached model predictions per photo/sailType |
| side | R2 sam3-seeds/ | server/sam3SeedCache.js:233 | sailscan-labels bucket (CF REST API, IP-restricted to Railway). SAM3 seed cache (recipe-revisioned) |
| side | R2 north-images/ | server/labelStore.js:1027 | sailscan-labels bucket (CF REST API, IP-restricted to Railway). North Sails external images + original lines |
| side | R2 sail-ratings/ | server/labelStore.js:1111 | sailscan-labels bucket (CF REST API, IP-restricted to Railway). External Good/Bad ratings + excluded.json |
| side | R2 blind-ratings/ | server/labelStore.js:2367 | sailscan-labels bucket (CF REST API, IP-restricted to Railway). Blind A/B pair votes |
| side | R2 review-batches/ | server/labelStore.js:2072 | sailscan-labels bucket (CF REST API, IP-restricted to Railway). Review batch manifests |
| side | R2 model-votes/ | server/labelStore.js:1990 | sailscan-labels bucket (CF REST API, IP-restricted to Railway). Model vote lane |
| side | R2 matrix-notes/ | server/labelStore.js:1898 | sailscan-labels bucket (CF REST API, IP-restricted to Railway). Test-matrix notes |
| side | R2 gate0-ratings/ | server/labelStore.js:1858 | sailscan-labels bucket (CF REST API, IP-restricted to Railway). Gate0 ratings |
| side | R2 sam-edge-ratings/ | server/labelStore.js:1792 | sailscan-labels bucket (CF REST API, IP-restricted to Railway). SAM edge ratings |
| side | R2 spinnaker-* | server/labelStore.js:1619 | sailscan-labels bucket (CF REST API, IP-restricted to Railway). spinnaker-images/ + spinnaker-labels/ |
| main | R2 instrument-images/ | server/labelStore.js:1663 | sailscan-labels bucket (CF REST API, IP-restricted to Railway). Instrument photos (segregated) |
| main | R2 models/ | server/inference/app.py:57 | sailscan-labels bucket (CF REST API, IP-restricted to Railway). Model weights (.pt) pulled by sidecar |
| side | R2 winners/ backups/ training | server/scripts/backup-r2.mjs:1 | sailscan-labels bucket (CF REST API, IP-restricted to Railway). Training bundles, winners, backups (scripts only) |
| main | SQLite scan_analyses | server/scanAnalyses.js:9 | Compact analysis projection; human snapshot wins |
| main | SQLite scan_correlations | server/scanCorrelation.js:13 | clientScanId ↔ photoId + analysis_json |
| side | SQLite violated_rules | server/violatedRulesQueue.js:17 | VIOLATED RULES bucket |
| side | SQLite scan_verifications | server/scanVerifications.js:12 | SAM3 async verification rows |
| side | SQLite model_runs | server/modelRuns.js:8 | Model-run ledger |
| main | SQLite users/sessions/devices | server/db.js:19 | Auth: users, sessions, account_sessions, devices, passkeys, login_events |
| main | SQLite accounts/boats/sails | server/db.js:112 | Teams, boats, sails, sail_targets, upload_links, feed_posts, comments… |
| side | SQLite user_photos / scan_flags | server/userPhotos.js:7 | user_photos, scan_flags, pending_human_corrections, customer_correction_index |
| side | SQLite model_ranking_* | server/modelRankingStore.js:13 | model_ranking_predictions, personal_model_rankings/ranks |
| side | SQLite error_log/recommendation_log/access_hours | server/errorLog.js:10 | Ops logs |
| legacy | rating-data.json (local disk) | server/ratingStore.js:1 | Legacy rating store; /api/analyze still upsertAnalysis()s every non-skipStore scan into it (index.js:513). Railway disk is ephemeral. |
| side | training-data/labels.jsonl (gitignored) | server/inference/train.py:1 | North convert output + R2 labels → train.py; holdout ids excluded (test-holdout-ids-canonical.json). |
| side | env UNIFIED_ANALYZE | server/index.js:464 | Selects unified chain for /api/analyze. CODE DEFAULT OFF (index.js:460 comment). Prod value not verified from code. |
| side | env SAM3_PRODUCTION_ENABLED | server/index.js:473 | SAM3 refine on customer scans (both paths). |
| side | env SAM3_REFINE_GUARD | server/qcStages.js:61 | Per-stripe accept/revert after SAM3 (>3% diag). |
| side | env POST_SAM3_EDGE_CLIP | server/inference/rule_checker.mjs:446 | finalizeStripes clip (+POST_SAM3_EDGE_EXTEND). Default OFF. |
| side | env RULES_REPAIR | server/inference/rule_checker.mjs:535 | finalizeStripes try-to-fix → recheck. Default OFF → flag only. |
| side | env EDGE_SNAP_EXTEND | server/inference/app.py:211 | Sidecar /edge-snap extends lines to sail edge. |
| side | env AUTO_FOOT_DOWN | server/pipeline/modes/cv.js:155 | cv.js default ON; index.js envFlagOn (labeler seed) default per envFlagOn. |
| side | env TOPPER / toppers | server/inference/app.py:1915 | Global TOPPER env or per-request toppers list (conditioned, refiner, polynms, verifier, edges, gaphunt, family). |
| side | env SHAPE_CHECK_ALWAYS_RESAMPLE | server/pipeline/stripeFilters.js:104 | Escape hatch; model lines always resampled to 10 pts. |
| side | env INFERENCE_URL | server/pipeline/modes/cv.js:2 | Required; missing → 503. |
| main | analyze() | server/pipeline/index.js:35 | Legacy path. runCv → finalizeAnalysis → enforceStripeGeometry (drop crossers) → geometryGuard attestation → stripe mask. Legacy path remains reachable via flag-off analyze, sail-type, model-preview and ranking prediction. |
| main | runCv() | server/pipeline/modes/cv.js:179 | EXIF-normalize, foot-down rotate (AUTO_FOOT_DOWN), rotation retries, variants, optional SAM3 refine, unrotate. |
| main | findFootDownRotation() | server/pipeline/modes/cv.js:121 | — |
| main | predictViaSidecar() | server/pipeline/modes/cv.js:63 | POST INFERENCE_URL/predict-coords (model, toppers optional). |
| main | selectModelStripes() | server/pipeline/modes/cv.js:261 | runCvInner with refineWithSam3:false — used as the unified chain finder. |
| main | buildCvResult() + boom gate | server/pipeline/modes/cv.js:550 | applyBoomRules (suppression, then boom gate ~756). |
| main | filterModelCandidates() | server/pipeline/modes/cv.js:545 | — |
| side | refineSelectedPrediction() / finishRefinementRules() | server/pipeline/sam3Refinement.js:68 | Legacy SAM3 refine; checkRules before/after (flag only). |
| main | finalizeAnalysis() | server/pipeline/index.js:162 | Wraps finalizeStripes for every analyze() caller; recomputes metrics if repaired. |
| main | analyzeViaSailPipeline() | server/index.js:2216 | Unified: preprocess → runPrecomputeChain("mem-analyze") → createSailAnalysis. No R2 write. |
| main | runPrecomputeChain() | server/qcStages.js:525 | bottom → finder → boom → edge → SAM3-refine → finalizeStripes. |
| main | Optional: bottom (/find-bottom) | server/qcStages.js:563 | — |
| main | stage finder (selectModelStripes + enforceStripeGeometry) | server/qcStages.js:366 | — |
| main | stage boom (/boom-only) | server/qcStages.js:381 | — |
| main | stage edge (/edge-snap + enforceStripeGeometry) | server/qcStages.js:394 | — |
| main | Optional: SAM3 refine (guard flag) | server/qcStages.js:440 | — |
| side | guardSam3Refined() | server/qcStages.js:72 | — |
| main | createSailAnalysis() | server/sailAnalysis.js:5 | computeLabelMetrics + SECOND checkAllRules (flag) + carries finalize attestation. |
| main | finalizeStripes() | server/inference/rule_checker.mjs:556 | THE ONE FINALIZER: post-SAM3 clip (env) → repairRuleViolations (RULES_REPAIR) or checkAllRules → ruleFlags attestation. |
| main | checkAllRules() | server/inference/rule_checker.mjs:215 | All 8 rules → {violations, hardFail}. |
| side | checkRules() | server/inference/rule_checker.mjs:76 | — |
| side | repairRuleViolations() | server/inference/rule_checker.mjs:617 | Env-gated RULES_REPAIR. |
| side | postSam3EdgeClip() | server/inference/rule_checker.mjs:455 | — |
| main | enforceStripeGeometry() | server/stripeMetrics.js:715 | Only real REPAIR everywhere: drop/revert crossers. |
| main | checkStripeCrossing() | server/stripeMetrics.js:949 | — |
| main | filterStripes() | server/pipeline/stripeFilters.js:557 | — |
| main | isGeometryViolation() | server/pipeline/stripeFilters.js:430 | — |
| main | applyBoomRules() | server/pipeline/stripeFilters.js:460 | — |
| main | computeStripeMetrics / computeTwist | server/stripeMetrics.js:163 | THE metric authority. |
| main | computeLabelMetrics() | server/stripeMetrics.js:494 | — |
| main | renderOverlay() | server/overlayRenderer.js:87 | — |
| side | computeSam3Seed() | server/sam3SeedCache.js:286 | enforceStripeGeometry only (line 327) — NO finalizeStripes/checkAllRules. |
| side | fetchSam3Predict() | server/sam3Live.js:77 | — |
| main | fetchSam3RefineLinesServerless() | server/sam3ServerlessSync.js:274 | — |
| side | enqueueVerification() | server/sam3Verify.js:62 | — |
| main | scanCorrelation reconcile() | server/scanCorrelation.js:79 | ONLY writer of violated_rules (recordViolation) — only for app scans with clientScanId. |
| side | recordViolation() | server/violatedRulesQueue.js:45 | — |
| main | saveScanAnalysis / saveLabelAnalysisSnapshot | server/scanAnalyses.js:50 | — |
| legacy | upsertAnalysis(ratingStore) | server/index.js:513 | Every non-skipStore /api/analyze writes the legacy local rating store. |
| main | computeRecommendations() | server/index.js:482 | — |
| unknown | sidecar GET /preview | server/inference/app.py:382 | Static preview page |
| side | sidecar GET /health | server/inference/app.py:392 | Health + model version (Railway/smoke) |
| side | sidecar GET /models | server/inference/app.py:1534 | PREVIEW_MODELS registry + checkpointSha256 |
| main | sidecar POST /predict-coords | server/inference/app.py:1948 | image(+sail_type, model, strict_preview, toppers) → keypoint polylines (PIXELS) + boom/outline |
| main | sidecar POST /edge-snap | server/inference/app.py:2259 | lines → edge-snapped lines + sail outline (EDGE_MODEL_PATH) |
| main | sidecar POST /boom-only | server/inference/app.py:2304 | image → boom line (BOOM_MODEL_PATH) |
| main | sidecar POST /find-bottom | server/inference/app.py:2331 | image → foot midpoint/rotation |
| side | TOPPER_REGISTRY | server/inference/app.py:1915 | conditioned, refiner, polynms, verifier, edges, gaphunt, family — applied inside /predict-coords when requested. |
| main | GET /api/scans/:photoId/verification | server/index.js:321 | Status lookup only: SQLite verification and correlation records. Does not run inference or read R2 images. |
| side | POST /api/predict-coords | server/index.js:356 | callers: scripts[server/inference/app.py] · handler mentions SAM3. touches: analyze(), predictViaSidecar/INFERENCE_URL, finalizeStripes, SAM3 |
| side | app.py | server/inference/app.py:1 | Script / eval / ops tool calling the API |
| main | POST /api/analyze | server/index.js:421 | callers: mobile[src/api.ts, src/backgroundScans.ts, src/parse.ts]; desktop[desktop/src/lib/api.ts]; scripts[scripts/smoke/server.sh, server/scripts/check-no-pipeline-duplication.js, server/inference/app.py, server/inference/auto-retrain.sh, server/inference/boom_gallery_fetch.mjs, server/inference/classify-north-sail-types.mjs] · handler mentions SAM3. touches: analyze(), predictViaSidecar/INFERENCE_URL, runQcStages/qcStages, SAM3 |
| side | server.sh | scripts/smoke/server.sh:1 | Script / eval / ops tool calling the API |
| side | check-no-pipeline-duplication.js | server/scripts/check-no-pipeline-duplication.js:1 | Script / eval / ops tool calling the API |
| side | auto-retrain.sh | server/inference/auto-retrain.sh:1 | Script / eval / ops tool calling the API |
| side | boom_gallery_fetch.mjs | server/inference/boom_gallery_fetch.mjs:1 | Script / eval / ops tool calling the API |
| side | classify-north-sail-types.mjs | server/inference/classify-north-sail-types.mjs:1 | Script / eval / ops tool calling the API |
| side | POST /api/model-preview | server/index.js:590 | callers: labeler[labeler/web/src/lib/labels.ts]; scripts[server/inference/cape31_baseline_sweep.mjs, server/inference/prod_baseline_fetch.mjs]. touches: analyze(), predictViaSidecar/INFERENCE_URL |
| side | cape31_baseline_sweep.mjs | server/inference/cape31_baseline_sweep.mjs:1 | Script / eval / ops tool calling the API |
| side | prod_baseline_fetch.mjs | server/inference/prod_baseline_fetch.mjs:1 | Script / eval / ops tool calling the API |
| side | GET /api/model-preview/models | server/index.js:633 | callers: labeler[labeler/web/src/lib/labels.ts]. touches: predictViaSidecar/INFERENCE_URL |
| main | POST /api/client-errors | server/index.js:650 | callers: mobile[src/api.ts]. touches: — |
| side | GET /api/errors/recent | server/index.js:659 | callers: scripts[scripts/signup-ntfy-poller.mjs, server/scripts/error-alert-poller.sh]. touches: — |
| side | signup-ntfy-poller.mjs | scripts/signup-ntfy-poller.mjs:1 | Script / eval / ops tool calling the API |
| side | error-alert-poller.sh | server/scripts/error-alert-poller.sh:1 | Script / eval / ops tool calling the API |
| unknown | GET /api/labels/:photoId/pending-corrections | server/index.js:670 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| main | POST /api/labels | server/index.js:676 | callers: mobile[src/api.ts]; labeler[labeler/web/src/components/FixExternalPage.tsx, labeler/web/src/components/ReviewPage.tsx, labeler/web/src/lib/boomBlitz.ts, labeler/web/src/lib/fixExternal.ts, labeler/web/src/lib/labels.ts]; desktop[desktop/src/lib/api.ts, desktop/src/lib/devMock.ts, desktop/src/lib/labelPayload.ts, desktop/src/lib/types.ts]; scripts[server/inference/train.py, server/inference/train_boom.py, server/rating-cf/public/app.js]. touches: overlayRenderer |
| side | train.py | server/inference/train.py:1 | Script / eval / ops tool calling the API |
| side | train_boom.py | server/inference/train_boom.py:1 | Script / eval / ops tool calling the API |
| side | app.js | server/rating-cf/public/app.js:1 | Script / eval / ops tool calling the API |
| side | GET /api/ai-corrections/pending | server/index.js:931 | callers: labeler[labeler/web/src/lib/aiCorrections.ts]. touches: — |
| side | POST /api/ai-corrections/:photoId/review | server/index.js:958 | callers: labeler[labeler/web/src/lib/aiCorrections.ts]. touches: overlayRenderer |
| side | GET /api/admin/user-corrections | server/index.js:1049 | callers: labeler[labeler/web/src/lib/customerCorrections.ts]. touches: — |
| side | POST /api/admin/user-corrections/:photoId/decision | server/index.js:1088 | callers: labeler[labeler/web/src/lib/customerCorrections.ts]. touches: — |
| main | POST /api/photos | server/index.js:1152 | callers: mobile[src/api.ts]; labeler[labeler/web/src/components/CalculatedPage.tsx, labeler/web/src/lib/labels.ts, labeler/web/src/lib/modelVote.ts, labeler/web/src/lib/review.ts, labeler/web/src/lib/rotation.ts, labeler/web/src/types.ts]; desktop[desktop/src/components/ScanList.tsx, desktop/src/lib/api.ts, desktop/src/lib/types.ts]; scripts[scripts/smoke/server.sh, server/scripts/llm-orientation-pass.mjs, server/scripts/orientation-flagged-sheet.mjs, server/scripts/orientation-full.mjs, server/scripts/reflag-seeds.mjs, server/scripts/rules-census.mjs]. touches: predictViaSidecar/INFERENCE_URL |
| side | llm-orientation-pass.mjs | server/scripts/llm-orientation-pass.mjs:1 | Script / eval / ops tool calling the API |
| side | orientation-flagged-sheet.mjs | server/scripts/orientation-flagged-sheet.mjs:1 | Script / eval / ops tool calling the API |
| side | orientation-full.mjs | server/scripts/orientation-full.mjs:1 | Script / eval / ops tool calling the API |
| side | reflag-seeds.mjs | server/scripts/reflag-seeds.mjs:1 | Script / eval / ops tool calling the API |
| side | rules-census.mjs | server/scripts/rules-census.mjs:1 | Script / eval / ops tool calling the API |
| main | PATCH /api/photos/:photoId/details | server/index.js:1253 | callers: mobile[src/api.ts]; desktop[desktop/src/lib/api.ts]. touches: — |
| main | GET /api/scan-details/presets | server/index.js:1300 | callers: mobile[src/api.ts]. touches: — |
| main | GET /api/photos/mine | server/index.js:1325 | callers: labeler[labeler/web/src/lib/labels.ts]. touches: — |
| main | GET /api/scans/mine | server/index.js:1353 | callers: mobile[src/api.ts, src/serverScans.ts]; desktop[desktop/src/lib/api.ts, desktop/src/lib/devMock.ts, desktop/src/lib/types.ts]. touches: — |
| main | GET /api/photos/unlabeled | server/index.js:1398 | callers: labeler[labeler/web/src/lib/fixExternal.ts, labeler/web/src/lib/labels.ts]; scripts[server/scripts/llm-orientation-pass.mjs, server/scripts/orientation-full.mjs, server/scripts/reflag-seeds.mjs, server/scripts/rules-census.mjs, server/inference/experiments/boomcam-rules-audit-sail149-2/rule_gate.py, server/inference/fresh100_blind.mjs] · handler mentions SAM3. touches: SAM3 |
| side | rule_gate.py | server/inference/experiments/boomcam-rules-audit-sail149-2/rule_gate.py:1 | Script / eval / ops tool calling the API |
| side | fresh100_blind.mjs | server/inference/fresh100_blind.mjs:1 | Script / eval / ops tool calling the API |
| main | GET /api/review-batches | server/index.js:1439 | callers: labeler[labeler/web/src/lib/reviewBatches.ts]. touches: — |
| main | GET /api/review-batches/boom-cam | server/index.js:1466 | callers: labeler[labeler/web/src/lib/reviewBatches.ts]; scripts[server/inference/experiments/boomcam-rules-audit-sail149-2/rule_gate.py]. touches: — |
| main | GET /api/review-batches/boom-cam/test-sample | server/index.js:1483 | callers: labeler[labeler/web/src/lib/reviewBatches.ts]. touches: — |
| main | POST /api/review-batches | server/index.js:1504 | callers: labeler[labeler/web/src/lib/reviewBatches.ts]. touches: — |
| main | GET /api/review-batches/:id/sample | server/index.js:1528 | callers: labeler[labeler/web/src/lib/reviewBatches.ts]. touches: analyze() |
| main | POST /api/photos/:photoId/flag | server/index.js:1590 | callers: mobile[src/api.ts]. touches: — |
| main | POST /api/photos/:photoId/discard | server/index.js:1606 | callers: labeler[labeler/web/src/lib/labels.ts]. touches: — |
| unknown | GET /api/photos/flags | server/index.js:1621 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: analyze(), violatedRulesQueue |
| unknown | GET /api/violated-rules | server/index.js:1631 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | POST /api/violated-rules/:photoId/resolve | server/index.js:1638 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | POST /api/violated-rules/:photoId/flag | server/index.js:1647 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| main | GET /api/photos/:photoId/predict | server/index.js:1658 | callers: mobile[src/api.ts]; labeler[labeler/web/src/lib/labels.ts, labeler/web/src/lib/modelVote.ts, labeler/web/src/lib/review.ts]; desktop[desktop/src/lib/api.ts]; scripts[server/scripts/reflag-seeds.mjs, server/scripts/rules-census.mjs, server/scripts/tune-offsail-k.mjs] · handler mentions SAM3. touches: analyze(), predictViaSidecar/INFERENCE_URL, checkAllRules/checkRules, finalizeStripes, SAM3, orientation/footDown |
| side | tune-offsail-k.mjs | server/scripts/tune-offsail-k.mjs:1 | Script / eval / ops tool calling the API |
| main | POST /api/qc/stage/:name | server/index.js:1963 | callers: labeler[labeler/web/src/lib/labels.ts] · handler mentions SAM3. touches: predictViaSidecar/INFERENCE_URL, runQcStages/qcStages, enforceStripeGeometry, checkAllRules/checkRules, SAM3, computeLabelMetrics, orientation/footDown |
| unknown | POST /api/sam3-seeds/precompute | server/index.js:2305 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference) · handler mentions SAM3. touches: SAM3 |
| unknown | GET /api/sam3-seeds/precompute/status | server/index.js:2313 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference) · handler mentions SAM3. touches: SAM3 |
| main | GET /api/labels/boomless | server/index.js:2375 | callers: labeler[labeler/web/src/lib/boomBlitz.ts] · handler mentions SAM3. touches: SAM3 |
| side | GET /api/labels/sam3-disagreement-queue | server/index.js:2454 | callers: scripts[server/inference/sam3_qc_rank_export.mjs] · handler mentions SAM3. touches: SAM3 |
| side | sam3_qc_rank_export.mjs | server/inference/sam3_qc_rank_export.mjs:1 | Script / eval / ops tool calling the API |
| main | POST /api/labels/:photoId/boom | server/index.js:2469 | callers: labeler[labeler/web/src/lib/boomBlitz.ts]. touches: — |
| side | GET /api/sail-ratings/unrated | server/index.js:2535 | callers: labeler[labeler/web/src/lib/sailRating.ts]. touches: — |
| side | GET /api/sail-ratings/:id/lines | server/index.js:2550 | callers: labeler[labeler/web/src/lib/fixExternal.ts, labeler/web/src/lib/sailRating.ts]. touches: enforceStripeGeometry |
| side | GET /api/sail-ratings/excluded | server/index.js:2586 | callers: scripts[server/inference/auto-retrain.sh, server/inference/fetch-exclusions.mjs, server/inference/retrain-local.sh, server/inference/train.py]. touches: — |
| side | fetch-exclusions.mjs | server/inference/fetch-exclusions.mjs:1 | Script / eval / ops tool calling the API |
| side | retrain-local.sh | server/inference/retrain-local.sh:1 | Script / eval / ops tool calling the API |
| side | GET /api/sail-ratings/relabel | server/index.js:2626 | callers: labeler[labeler/web/src/lib/fixExternal.ts]. touches: — |
| side | POST /api/sail-ratings/:id | server/index.js:2647 | callers: labeler[labeler/web/src/lib/fixExternal.ts, labeler/web/src/lib/sailRating.ts]; scripts[server/inference/auto-retrain.sh, server/inference/fetch-exclusions.mjs, server/inference/retrain-local.sh, server/inference/train.py]. touches: — |
| side | POST /api/sail-ratings/:id/discard | server/index.js:2672 | callers: labeler[labeler/web/src/lib/fixExternal.ts]. touches: — |
| side | GET /api/sam-edge-ratings | server/index.js:2698 | callers: labeler[labeler/web/src/lib/samEdge.ts]. touches: — |
| side | POST /api/sam-edge-ratings/:id | server/index.js:2707 | callers: labeler[labeler/web/src/lib/samEdge.ts]. touches: — |
| side | GET /api/gate0-ratings | server/index.js:2732 | callers: scripts[server/inference/gate0-audit-gallery/index.html, server/inference/gate0_render_audit_gallery.py]. touches: — |
| side | index.html | server/inference/gate0-audit-gallery/index.html:1 | Script / eval / ops tool calling the API |
| side | gate0_render_audit_gallery.py | server/inference/gate0_render_audit_gallery.py:1 | Script / eval / ops tool calling the API |
| side | POST /api/gate0-ratings/:id | server/index.js:2741 | callers: scripts[server/inference/gate0-audit-gallery/index.html, server/inference/gate0_render_audit_gallery.py]. touches: — |
| side | GET /api/matrix-notes | server/index.js:2764 | Active external caller documented in docs/test-matrix/pending-notes-3.1-3.3.md; not a proven dead route. |
| side | POST /api/matrix-notes/:rowId | server/index.js:2773 | Active external caller documented in docs/test-matrix/pending-notes-3.1-3.3.md; not a proven dead route. |
| side | GET /api/model-votes/batch | server/index.js:2815 | callers: labeler[labeler/web/src/lib/modelVote.ts]. touches: — |
| side | POST /api/model-votes/:photoId | server/index.js:2842 | callers: labeler[labeler/web/src/lib/modelVote.ts]. touches: — |
| side | GET /api/model-votes/tally | server/index.js:2871 | callers: labeler[labeler/web/src/lib/modelVote.ts]. touches: — |
| main | POST /api/instrument-photos | server/index.js:2892 | callers: mobile[src/api.ts]. touches: — |
| main | GET /api/instrument-photos/:id | server/index.js:2903 | callers: mobile[src/api.ts]. touches: — |
| side | POST /api/spinnaker/photos | server/index.js:2927 | callers: labeler[labeler/web/src/lib/spinnaker.ts]. touches: — |
| side | GET /api/spinnaker/unlabeled | server/index.js:2941 | callers: labeler[labeler/web/src/lib/spinnaker.ts]. touches: predictViaSidecar/INFERENCE_URL |
| side | GET /api/spinnaker/photos/:id/predict | server/index.js:2958 | callers: labeler[labeler/web/src/lib/spinnaker.ts]. touches: — |
| side | POST /api/spinnaker/predict | server/index.js:2963 | callers: scripts[server/inference/app.py, server/inference/train_spinnaker.py]. touches: — |
| side | train_spinnaker.py | server/inference/train_spinnaker.py:1 | Script / eval / ops tool calling the API |
| side | GET /api/spinnaker/photos/:id | server/index.js:2967 | callers: labeler[labeler/web/src/lib/spinnaker.ts]. touches: — |
| side | POST /api/spinnaker/labels | server/index.js:2981 | callers: labeler[labeler/web/src/lib/spinnaker.ts]. touches: — |
| unknown | GET /api/recommendations/recent | server/index.js:3015 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | GET /api/access/summary | server/index.js:3021 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| main | GET /api/photos/:photoId/overlay | server/index.js:3036 | callers: labeler[labeler/web/src/lib/labels.ts]; desktop[desktop/src/lib/api.ts]; scripts[scripts/smoke/server.sh]. touches: overlayRenderer |
| main | GET /api/photos/:photoId | server/index.js:3081 | callers: mobile[src/api.ts]; labeler[labeler/web/src/components/CalculatedPage.tsx, labeler/web/src/lib/fixExternal.ts, labeler/web/src/lib/labels.ts]; desktop[desktop/src/lib/api.ts]; scripts[server/scripts/llm-orientation-pass.mjs, server/scripts/orientation-flagged-sheet.mjs, server/scripts/orientation-full.mjs, server/scripts/reflag-seeds.mjs, server/scripts/rules-census.mjs, server/inference/experiments/boomcam-rules-audit-sail149-2/rule_gate.py]. touches: — |
| main | GET /api/photos/:photoId/thumb | server/index.js:3137 | callers: mobile[src/api.ts]; labeler[labeler/web/src/lib/labels.ts]; desktop[desktop/src/components/ScanList.tsx]. touches: — |
| side | GET /api/labels/stats | server/index.js:3176 | callers: scripts[server/inference/auto-loop/lib/trigger.mjs, server/inference/auto-loop/loop.mjs, server/inference/auto-retrain.sh]. touches: — |
| side | trigger.mjs | server/inference/auto-loop/lib/trigger.mjs:1 | Script / eval / ops tool calling the API |
| side | loop.mjs | server/inference/auto-loop/loop.mjs:1 | Script / eval / ops tool calling the API |
| main | GET /api/labels/list | server/index.js:3189 | callers: labeler[labeler/web/src/components/CalculatedPage.tsx, labeler/web/src/components/Gallery.tsx, labeler/web/src/components/GalleryPage.tsx, labeler/web/src/lib/labels.ts, labeler/web/src/lib/modelRanking.ts]; scripts[scripts/smoke/server.sh, server/inference/auto-retrain.sh, server/rating-cf/public/app.js]. touches: computeLabelMetrics |
| main | GET /api/labels/:photoId/metrics | server/index.js:3216 | callers: desktop[desktop/src/lib/api.ts]; scripts[server/rating-cf/public/app.js]. touches: computeLabelMetrics |
| main | GET /api/labels/:photoId | server/index.js:3245 | callers: labeler[labeler/web/src/components/CalculatedPage.tsx, labeler/web/src/components/Gallery.tsx, labeler/web/src/components/GalleryPage.tsx, labeler/web/src/lib/boomBlitz.ts, labeler/web/src/lib/labels.ts, labeler/web/src/lib/modelRanking.ts]; scripts[scripts/smoke/server.sh, server/inference/auto-loop/lib/trigger.mjs, server/inference/auto-loop/loop.mjs, server/inference/auto-retrain.sh, server/inference/sam3_qc_rank_export.mjs, server/rating-cf/public/app.js]. touches: — |
| main | DELETE /api/labels/:photoId | server/index.js:3258 | callers: labeler[labeler/web/src/components/CalculatedPage.tsx, labeler/web/src/components/Gallery.tsx, labeler/web/src/components/GalleryPage.tsx, labeler/web/src/lib/boomBlitz.ts, labeler/web/src/lib/labels.ts, labeler/web/src/lib/modelRanking.ts]; scripts[scripts/smoke/server.sh, server/inference/auto-loop/lib/trigger.mjs, server/inference/auto-loop/loop.mjs, server/inference/auto-retrain.sh, server/inference/sam3_qc_rank_export.mjs, server/rating-cf/public/app.js]. touches: — |
| side | GET /api/boats | server/index.js:3273 | callers: scripts[scripts/smoke/server.sh]. touches: — |
| unknown | GET /api/boats/:name/sails | server/index.js:3279 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | GET /api/crossover | server/index.js:3287 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | GET /api/crossover/validate | server/index.js:3295 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | GET /api/crossover/suggest | server/index.js:3306 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | POST /api/compare | server/index.js:3322 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | POST /api/recommendations | server/index.js:3400 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | GET /api/debug-images | server/index.js:3458 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| side | GET /api/rating/items | server/index.js:3494 | callers: scripts[server/rating-ui/app.js, server/rating-cf/functions/api/rating/items.js, server/rating-cf/public/app.js]. touches: — |
| side | app.js | server/rating-ui/app.js:1 | Script / eval / ops tool calling the API |
| side | items.js | server/rating-cf/functions/api/rating/items.js:1 | Script / eval / ops tool calling the API |
| side | POST /api/rating/:id | server/index.js:3513 | callers: scripts[server/rating-ui/app.js, server/rating-cf/functions/api/rating/items.js, server/rating-cf/functions/api/rating/upload.js, server/rating-cf/public/app.js]. touches: — |
| side | upload.js | server/rating-cf/functions/api/rating/upload.js:1 | Script / eval / ops tool calling the API |
| unknown | POST /api/rating/rerun/:id | server/index.js:3528 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | POST /api/rating/rerun-all | server/index.js:3547 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| side | GET /ping | server/index.js:3600 | callers: scripts[scripts/smoke/server.sh, server/inference/boom_gallery_suite.sh, server/inference/holdout_suite.sh, server/inference/oracle_dump.sh, server/inference/pod-finder-moredata.sh] · handler mentions SAM3. touches: SAM3 |
| side | boom_gallery_suite.sh | server/inference/boom_gallery_suite.sh:1 | Script / eval / ops tool calling the API |
| side | holdout_suite.sh | server/inference/holdout_suite.sh:1 | Script / eval / ops tool calling the API |
| side | oracle_dump.sh | server/inference/oracle_dump.sh:1 | Script / eval / ops tool calling the API |
| side | pod-finder-moredata.sh | server/inference/pod-finder-moredata.sh:1 | Script / eval / ops tool calling the API |
| main | POST /api/auth/register | server/routes/auth.js:34 | callers: mobile[src/api.ts]. touches: — |
| unknown | POST /api/auth/transfer/generate | server/routes/auth.js:67 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | POST /api/auth/transfer/claim | server/routes/auth.js:82 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| main | POST /api/auth/signup | server/routes/webAuth.js:138 | callers: mobile[src/api.ts]; labeler[labeler/web/src/lib/sailscan-auth.ts]; desktop[desktop/src/lib/sailscan-auth.ts]. touches: — |
| main | POST /api/auth/login | server/routes/webAuth.js:211 | callers: mobile[src/api.ts]; labeler[labeler/web/src/lib/sailscan-auth.ts]; desktop[desktop/src/lib/devMock.ts, desktop/src/lib/sailscan-auth.ts]. touches: — |
| main | POST /api/auth/forgot | server/routes/webAuth.js:271 | callers: mobile[src/api.ts]; labeler[labeler/web/src/lib/sailscan-auth.ts]; desktop[desktop/src/lib/sailscan-auth.ts]. touches: — |
| main | POST /api/auth/reset | server/routes/webAuth.js:307 | callers: mobile[src/api.ts]; labeler[labeler/web/src/lib/sailscan-auth.ts]; desktop[desktop/src/lib/sailscan-auth.ts]. touches: — |
| main | POST /api/auth/logout | server/routes/webAuth.js:360 | callers: mobile[src/api.ts]; labeler[labeler/web/src/lib/sailscan-auth.ts]; desktop[desktop/src/lib/devMock.ts, desktop/src/lib/sailscan-auth.ts]. touches: — |
| main | GET /api/auth/me | server/routes/webAuth.js:366 | callers: mobile[src/api.ts]; labeler[labeler/web/src/lib/sailscan-auth.ts]; desktop[desktop/src/lib/devMock.ts, desktop/src/lib/sailscan-auth.ts]; scripts[scripts/smoke/contract.mjs, scripts/smoke/server.sh]. touches: — |
| side | contract.mjs | scripts/smoke/contract.mjs:1 | Script / eval / ops tool calling the API |
| side | GET /api/auth/signups/recent | server/routes/webAuth.js:375 | callers: scripts[scripts/signup-ntfy-poller.mjs, server/scripts/error-alert-poller.sh]. touches: — |
| unknown | GET /api/auth/chat-signups/recent | server/routes/webAuth.js:392 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | GET /api/auth/chat-signups/rejected | server/routes/webAuth.js:409 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | POST /api/auth/chat-signups/:eventId/decision | server/routes/webAuth.js:420 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| side | GET /api/auth/users | server/routes/webAuth.js:456 | callers: labeler[labeler/web/src/lib/auth.ts]. touches: — |
| main | GET /api/auth/settings | server/routes/webAuth.js:464 | callers: mobile[src/api.ts]. touches: — |
| unknown | PATCH /api/auth/settings/ai-rate-limits | server/routes/webAuth.js:479 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| main | PATCH /api/auth/settings/auto-approval | server/routes/webAuth.js:494 | callers: mobile[src/api.ts]. touches: — |
| main | PUT /api/auth/settings/preapproved-emails | server/routes/webAuth.js:503 | callers: mobile[src/api.ts]. touches: — |
| side | POST /api/auth/users/:id/approve | server/routes/webAuth.js:513 | callers: labeler[labeler/web/src/lib/auth.ts]. touches: — |
| side | POST /api/auth/users/:id/disable | server/routes/webAuth.js:520 | callers: labeler[labeler/web/src/lib/auth.ts]. touches: — |
| side | GET /api/auth/access-log | server/routes/webAuth.js:529 | callers: labeler[labeler/web/src/lib/auth.ts]. touches: — |
| main | POST /api/feedback | server/routes/feedback.js:47 | callers: mobile[src/api.ts]. touches: — |
| main | GET /api/profile | server/routes/profile.js:25 | callers: desktop[desktop/src/lib/api.ts, desktop/src/lib/devMock.ts]. touches: — |
| main | PATCH /api/profile | server/routes/profile.js:62 | callers: desktop[desktop/src/lib/api.ts, desktop/src/lib/devMock.ts]. touches: — |
| unknown | POST /api/teams | server/routes/teams.js:75 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | GET /api/teams | server/routes/teams.js:110 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | POST /api/teams/:id/invite | server/routes/teams.js:138 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | POST /api/teams/join | server/routes/teams.js:176 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | DELETE /api/teams/:id/members/:userId | server/routes/teams.js:232 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | DELETE /api/teams/:id | server/routes/teams.js:265 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | POST /api/teams/:id/analyses | server/routes/teams.js:288 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | GET /api/teams/:id/analyses | server/routes/teams.js:317 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| main | GET /api/accounts | server/routes/accounts.js:496 | callers: desktop[desktop/src/components/ScanList.tsx, desktop/src/lib/api.ts, desktop/src/lib/boatCrew.ts, desktop/src/lib/boatMetrics.ts, desktop/src/lib/devMock.ts]; scripts[scripts/doyle-live-smoke.mjs, scripts/smoke/server.sh]. touches: — |
| side | doyle-live-smoke.mjs | scripts/doyle-live-smoke.mjs:1 | Script / eval / ops tool calling the API |
| main | POST /api/accounts | server/routes/accounts.js:506 | callers: desktop[desktop/src/components/ScanList.tsx, desktop/src/lib/api.ts, desktop/src/lib/boatCrew.ts, desktop/src/lib/boatMetrics.ts, desktop/src/lib/devMock.ts]; scripts[scripts/doyle-live-smoke.mjs, scripts/smoke/server.sh]. touches: — |
| main | POST /api/accounts/join | server/routes/accounts.js:555 | callers: desktop[desktop/src/lib/api.ts, desktop/src/lib/devMock.ts]. touches: — |
| main | GET /api/accounts/:id | server/routes/accounts.js:634 | callers: desktop[desktop/src/lib/api.ts, desktop/src/lib/boatCrew.ts, desktop/src/lib/devMock.ts]. touches: — |
| main | PATCH /api/accounts/:id | server/routes/accounts.js:638 | callers: desktop[desktop/src/lib/api.ts, desktop/src/lib/boatCrew.ts, desktop/src/lib/devMock.ts]. touches: — |
| main | PATCH /api/accounts/:id/brand | server/routes/accounts.js:674 | callers: desktop[desktop/src/lib/api.ts]. touches: — |
| main | DELETE /api/accounts/:id | server/routes/accounts.js:707 | callers: desktop[desktop/src/lib/api.ts, desktop/src/lib/boatCrew.ts, desktop/src/lib/devMock.ts]. touches: — |
| main | GET /api/accounts/:id/members | server/routes/accounts.js:718 | callers: desktop[desktop/src/lib/api.ts]. touches: — |
| main | GET /api/accounts/:id/invites | server/routes/accounts.js:743 | callers: desktop[desktop/src/lib/api.ts]. touches: — |
| main | POST /api/accounts/:id/invites | server/routes/accounts.js:774 | callers: desktop[desktop/src/lib/api.ts]. touches: — |
| main | DELETE /api/accounts/:id/invites/:code | server/routes/accounts.js:812 | callers: desktop[desktop/src/lib/api.ts]. touches: — |
| main | PATCH /api/accounts/:id/members/:userId | server/routes/accounts.js:834 | callers: desktop[desktop/src/lib/api.ts]. touches: — |
| main | DELETE /api/accounts/:id/members/:userId | server/routes/accounts.js:860 | callers: desktop[desktop/src/lib/api.ts]. touches: — |
| main | GET /api/accounts/:id/audit | server/routes/accounts.js:884 | callers: desktop[desktop/src/lib/api.ts]. touches: — |
| main | GET /api/accounts/:id/boats | server/routes/accounts.js:910 | callers: desktop[desktop/src/lib/api.ts, desktop/src/lib/devMock.ts]. touches: — |
| main | POST /api/accounts/:id/boats | server/routes/accounts.js:917 | callers: desktop[desktop/src/lib/api.ts, desktop/src/lib/devMock.ts]. touches: — |
| unknown | GET /api/accounts/:id/boats/:boatId | server/routes/accounts.js:928 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | PATCH /api/accounts/:id/boats/:boatId | server/routes/accounts.js:934 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | DELETE /api/accounts/:id/boats/:boatId | server/routes/accounts.js:952 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| main | GET /api/accounts/:id/boats/:boatId/sails | server/routes/accounts.js:959 | callers: desktop[desktop/src/lib/api.ts]. touches: — |
| main | POST /api/accounts/:id/boats/:boatId/sails | server/routes/accounts.js:967 | callers: desktop[desktop/src/lib/api.ts]. touches: — |
| unknown | GET /api/accounts/:id/sails/:sailId | server/routes/accounts.js:981 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | PATCH /api/accounts/:id/sails/:sailId | server/routes/accounts.js:987 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | DELETE /api/accounts/:id/sails/:sailId | server/routes/accounts.js:1013 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| main | GET /api/accounts/:id/sessions | server/routes/accounts.js:1022 | callers: desktop[desktop/src/lib/api.ts, desktop/src/lib/devMock.ts]. touches: — |
| main | POST /api/accounts/:id/sessions | server/routes/accounts.js:1031 | callers: desktop[desktop/src/lib/api.ts, desktop/src/lib/devMock.ts]. touches: — |
| unknown | GET /api/accounts/:id/sessions/:sessionId | server/routes/accounts.js:1050 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| main | GET /api/accounts/:id/sessions/:sessionId/report | server/routes/accounts.js:1056 | callers: desktop[desktop/src/lib/api.ts]. touches: — |
| unknown | PATCH /api/accounts/:id/sessions/:sessionId | server/routes/accounts.js:1154 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | DELETE /api/accounts/:id/sessions/:sessionId | server/routes/accounts.js:1175 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| main | GET /api/accounts/:id/scans | server/routes/accounts.js:1229 | callers: desktop[desktop/src/components/ScanList.tsx, desktop/src/lib/api.ts, desktop/src/lib/devMock.ts]. touches: — |
| main | POST /api/accounts/:id/scans/:scanId | server/routes/accounts.js:1269 | callers: desktop[desktop/src/lib/api.ts]. touches: — |
| main | GET /api/accounts/:id/scans/:scanId | server/routes/accounts.js:1321 | callers: desktop[desktop/src/lib/api.ts]. touches: — |
| main | PATCH /api/accounts/:id/scans/:scanId | server/routes/accounts.js:1332 | callers: desktop[desktop/src/lib/api.ts]. touches: — |
| main | DELETE /api/accounts/:id/scans/:scanId | server/routes/accounts.js:1384 | callers: desktop[desktop/src/lib/api.ts]. touches: — |
| main | GET /api/accounts/:id/scans/:scanId/photo | server/routes/accounts.js:1423 | callers: desktop[desktop/src/lib/api.ts]. touches: — |
| main | GET /api/accounts/:id/scans/:scanId/overlay | server/routes/accounts.js:1440 | callers: desktop[desktop/src/lib/api.ts]. touches: — |
| main | GET /api/accounts/:id/scans/:scanId/thumb | server/routes/accounts.js:1453 | callers: desktop[desktop/src/components/ScanList.tsx]. touches: — |
| main | GET /api/accounts/:id/scans/:scanId/metrics | server/routes/accounts.js:1490 | callers: desktop[desktop/src/lib/api.ts]. touches: computeLabelMetrics |
| main | GET /api/accounts/:id/upload-links | server/routes/accounts.js:1507 | callers: desktop[desktop/src/lib/api.ts, desktop/src/lib/devMock.ts]. touches: — |
| main | POST /api/accounts/:id/upload-links | server/routes/accounts.js:1526 | callers: desktop[desktop/src/lib/api.ts, desktop/src/lib/devMock.ts]. touches: — |
| main | DELETE /api/accounts/:id/upload-links/:token | server/routes/accounts.js:1548 | callers: desktop[desktop/src/lib/api.ts]. touches: — |
| main | GET /u/:token | server/routes/accounts.js:1557 | callers: desktop[desktop/src/components/Organization.tsx, desktop/src/lib/publicUploadRedirect.ts]; scripts[server/inference/.venv/lib/python3.11/site-packages/sympy/polys/polyroots.py, server/inference/.venv/lib/python3.11/site-packages/transformers/modeling_rope_utils.py, server/inference/gate1-deeplsd-work/.venv-deeplsd/lib/python3.14/site-packages/sympy/polys/polyroots.py]. touches: — |
| side | polyroots.py | server/inference/.venv/lib/python3.11/site-packages/sympy/polys/polyroots.py:1 | Script / eval / ops tool calling the API |
| side | modeling_rope_utils.py | server/inference/.venv/lib/python3.11/site-packages/transformers/modeling_rope_utils.py:1 | Script / eval / ops tool calling the API |
| side | polyroots.py | server/inference/gate1-deeplsd-work/.venv-deeplsd/lib/python3.14/site-packages/sympy/polys/polyroots.py:1 | Script / eval / ops tool calling the API |
| unknown | POST /api/upload-links/:token/photos | server/routes/accounts.js:1564 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: analyze(), predictViaSidecar/INFERENCE_URL |
| unknown | GET /api/accounts/:id/boats/:boatId/crew | server/routes/boatCrew.js:40 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | PATCH /api/accounts/:id/boats/:boatId/privacy | server/routes/boatCrew.js:56 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | POST /api/accounts/:id/boats/:boatId/invites | server/routes/boatCrew.js:80 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | POST /api/accounts/:id/boat-invites/:token/accept | server/routes/boatCrew.js:105 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | PATCH /api/accounts/:id/boats/:boatId/crew/:userId | server/routes/boatCrew.js:140 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | DELETE /api/accounts/:id/boats/:boatId/crew/:userId | server/routes/boatCrew.js:189 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | GET /api/accounts/:id/scans/:scanId/comments | server/routes/boatCrew.js:218 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | POST /api/accounts/:id/scans/:scanId/comments | server/routes/boatCrew.js:247 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| main | GET /api/accounts/:id/boat-metrics | server/routes/boatMetrics.js:8 | callers: desktop[desktop/src/lib/boatMetrics.ts]. touches: — |
| main | GET /api/accounts/:id/sails/:sailId/targets | server/routes/boatMetrics.js:27 | callers: desktop[desktop/src/lib/boatMetrics.ts]. touches: — |
| main | POST /api/accounts/:id/sails/:sailId/targets | server/routes/boatMetrics.js:30 | callers: desktop[desktop/src/lib/boatMetrics.ts]. touches: — |
| main | GET /api/tenant | server/routes/tenant.js:40 | callers: desktop[desktop/src/lib/api.ts, desktop/src/lib/devMock.ts]; scripts[scripts/smoke/server.sh]. touches: — |
| unknown | POST /api/admin/tenant-domains | server/routes/tenant.js:54 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | DELETE /api/admin/tenant-domains/:hostname | server/routes/tenant.js:79 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| side | GET /api/doyle-demo/session | server/routes/doyleDemo.js:64 | callers: scripts[scripts/doyle-live-smoke.mjs]. touches: — |
| side | POST /api/doyle-demo/session | server/routes/doyleDemo.js:67 | callers: scripts[scripts/doyle-live-smoke.mjs]. touches: — |
| side | DELETE /api/doyle-demo/session | server/routes/doyleDemo.js:87 | callers: scripts[scripts/doyle-live-smoke.mjs]. touches: — |
| side | GET /api/doyle-demo/sails/:id/reference | server/routes/doyleDemo.js:104 | callers: scripts[scripts/doyle-live-smoke.mjs]. touches: — |
| side | PUT /api/doyle-demo/sails/:id/reference | server/routes/doyleDemo.js:108 | callers: scripts[scripts/doyle-live-smoke.mjs]. touches: — |
| main | GET /api/doyle-demo | server/routes/doyleDemo.js:115 | callers: desktop[desktop/src/components/DoyleDemo.tsx]; scripts[scripts/doyle-live-smoke.mjs]. touches: — |
| main | GET /api/scans/:photoId/analysis | server/routes/scans.js:153 | callers: mobile[src/api.ts]; desktop[desktop/src/lib/api.ts]. touches: — |
| main | GET /api/scans/:photoId/export-image | server/routes/scans.js:214 | callers: mobile[src/api.ts]; desktop[desktop/src/lib/api.ts]. touches: overlayRenderer |
| main | GET /api/scans/:photoId/export.jpg | server/routes/scans.js:357 | callers: desktop[desktop/src/lib/api.ts]. touches: — |
| main | GET /api/scans/:photoId/export.pdf | server/routes/scans.js:359 | callers: desktop[desktop/src/lib/api.ts]. touches: analyze(), predictViaSidecar/INFERENCE_URL, computeStripeMetrics |
| main | POST /api/scans/:photoId/sail-type | server/routes/scans.js:418 | callers: desktop[desktop/src/lib/api.ts]. touches: analyze(), predictViaSidecar/INFERENCE_URL, applyBoomRules, computeLabelMetrics, computeStripeMetrics |
| main | GET /api/scans/:photoId/sail-life | server/routes/scans.js:563 | callers: desktop[desktop/src/lib/api.ts]. touches: — |
| side | GET /api/model-runs | server/routes/modelRuns.js:23 | callers: scripts[server/inference/auto-retrain.sh, server/inference/holdout_suite.sh, server/inference/report-model-run.mjs, server/inference/retrain-local.sh]. touches: — |
| side | report-model-run.mjs | server/inference/report-model-run.mjs:1 | Script / eval / ops tool calling the API |
| side | POST /api/model-runs | server/routes/modelRuns.js:27 | callers: scripts[server/inference/auto-retrain.sh, server/inference/holdout_suite.sh, server/inference/report-model-run.mjs, server/inference/retrain-local.sh]. touches: — |
| main | GET /api/feed | server/routes/feed.js:45 | callers: mobile[src/api.ts]; desktop[desktop/src/lib/api.ts, desktop/src/lib/devMock.ts]; scripts[scripts/smoke/server.sh]. touches: — |
| main | POST /api/feed | server/routes/feed.js:66 | callers: mobile[src/api.ts]; desktop[desktop/src/lib/api.ts, desktop/src/lib/devMock.ts]; scripts[scripts/smoke/server.sh]. touches: computeLabelMetrics |
| main | DELETE /api/feed/:postId | server/routes/feed.js:96 | callers: mobile[src/api.ts]; desktop[desktop/src/lib/api.ts]. touches: — |
| unknown | GET /api/feed/:postId/photo | server/routes/feed.js:107 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | GET /api/feed/:postId/overlay | server/routes/feed.js:117 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| side | GET /api/model-ranking/default | server/modelRanking.js:32 | Active labeler caller: modelRanking.ts rankingRequest/predictRanking, consumed by ModelRankingPage.tsx. Server persistence is in use; localStorage is not the only store. |
| side | GET /api/model-ranking/batch | server/modelRanking.js:33 | Active labeler caller: modelRanking.ts rankingRequest/predictRanking, consumed by ModelRankingPage.tsx. Server persistence is in use; localStorage is not the only store. |
| side | POST /api/model-ranking/batches | server/modelRanking.js:36 | Active labeler caller: modelRanking.ts rankingRequest/predictRanking, consumed by ModelRankingPage.tsx. Server persistence is in use; localStorage is not the only store. |
| side | PUT /api/model-ranking/batches/:batchId/votes/:photoId | server/modelRanking.js:49 | Active labeler caller: modelRanking.ts rankingRequest/predictRanking, consumed by ModelRankingPage.tsx. Server persistence is in use; localStorage is not the only store. |
| side | POST /api/model-ranking/predict | server/modelRanking.js:55 | Active labeler caller: modelRanking.ts rankingRequest/predictRanking, consumed by ModelRankingPage.tsx. Server persistence is in use; localStorage is not the only store. |
| side | GET /api/blind-ratings/:batch | server/blindRatings.js:21 | callers: scripts[server/inference/blind_rating_unblind.mjs]. touches: — |
| side | blind_rating_unblind.mjs | server/inference/blind_rating_unblind.mjs:1 | Script / eval / ops tool calling the API |
| unknown | POST /api/blind-ratings/:batch/:pairId | server/blindRatings.js:31 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | DELETE /api/blind-ratings/:batch/:pairId | server/blindRatings.js:46 | callers: No caller found by literal scan (not proof of disuse) (literal path scan of src/, app/, labeler/web/src, desktop/src, site/, scripts/, server/scripts, server/inference). touches: — |
| unknown | STATIC /rating (static rating-ui) | server/index.js:3452 | Legacy rating UI static |
| unknown | STATIC /rating-images (static, labelAuth) | server/index.js:3456 | Legacy |
| unknown | STATIC /debug-images (static, labelAuth) | server/index.js:3457 | Legacy debug dumps |
| side | holdout_suite.sh → prod_baseline_fetch/score | server/inference/holdout_suite.sh:4 | Boots local server, POSTs 332 holdout to /api/analyze, writes model-run ledger. |
| side | pseudo_label.mjs | server/inference/pseudo_label.mjs:68 | checkAllRules → drop hardFail → training records. |
| side | reflag-seeds.mjs | server/scripts/reflag-seeds.mjs:127 | Re-checks seeds with checkAllRules (flag ledger). |
| side | blind_rating_unblind.mjs | server/inference/blind_rating_unblind.mjs:1 | Reads blind-ratings votes, unblinds pairs. |
| side | scripts/sam3-warm.mjs | scripts/sam3-warm.mjs:1 | Warms SAM3 serverless. |
| side | train.py | server/inference/train.py:1 | R2 labels + labels.jsonl → YOLOv8/26-pose; excludes holdout + /api/sail-ratings/excluded. |
| side | sail-scraper harvest-api.mjs (external) | — | Pulls North scans → api-out → convert-north-to-training → labels.jsonl. Nate command only. |
| side | backup-r2.mjs | server/scripts/backup-r2.mjs:1 | R2 backups. |
| main | EXIF-upright pixels + W,H | server/index.js:2219 | preprocessImage applies orientation before the chain. All coordinates normalized [0,1]. |
| main | finalizeStripes: optional repair + check | server/qcStages.js finalizeStripes call | Uses current W,H, boom, sail outline and reference lines. Repair requires RULES_REPAIR=1 (default off). Surviving violations may be returned. |
| main | Finalizer throws: stageErrors.finalize | server/qcStages.js finalize catch | Current behavior: catch records error and continues; chain can return stripes without ruleFlags. This is an attestation gap, not the proposed contract. |
| main | Return current-frame image + points | server/sailAnalysis.js:67 | Customer adapter returns analysisImage (frame string=foot-down even when rotation skipped), width, height and rotation alongside same-frame points. Legacy output maps back to upright display frame. |
| main | Duplicate checkAllRules (outline=null) | server/sailAnalysis.js:40 | Adapter rechecks without outline and then copies finalizer metadata. Can disagree with finalizer. Current behavior, slated for removal in plan. |
| proposed | PROPOSED: runStripePipeline(image, ctx) | docs/ONE-PIPELINE-PLAN.md | PROPOSED ONLY — not implemented. Normalized points, explicit image frame and real W,H at every stage. |
| proposed | PROPOSED: findBottom | docs/ONE-PIPELINE-PLAN.md | PROPOSED ONLY — not implemented. Normalized points, explicit image frame and real W,H at every stage. |
| proposed | PROPOSED: finder | docs/ONE-PIPELINE-PLAN.md | PROPOSED ONLY — not implemented. Normalized points, explicit image frame and real W,H at every stage. |
| proposed | PROPOSED: selectCandidates | docs/ONE-PIPELINE-PLAN.md | PROPOSED ONLY — not implemented. Normalized points, explicit image frame and real W,H at every stage. |
| proposed | PROPOSED: boom | docs/ONE-PIPELINE-PLAN.md | PROPOSED ONLY — not implemented. Normalized points, explicit image frame and real W,H at every stage. |
| proposed | PROPOSED: edgeClip | docs/ONE-PIPELINE-PLAN.md | PROPOSED ONLY — not implemented. Normalized points, explicit image frame and real W,H at every stage. |
| proposed | PROPOSED: refine (SAM3 optional, guarded) | docs/ONE-PIPELINE-PLAN.md | PROPOSED ONLY — not implemented. Normalized points, explicit image frame and real W,H at every stage. |
| proposed | PROPOSED: finalize: sole rules authority | docs/ONE-PIPELINE-PLAN.md | PROPOSED ONLY — not implemented. Normalized points, explicit image frame and real W,H at every stage. |
| proposed | PROPOSED: Return stripes + attestation | docs/ONE-PIPELINE-PLAN.md | PROPOSED ONLY — not implemented. Normalized points, explicit image frame and real W,H at every stage. |

## Relationships

| From | To | Kind | Condition | Evidence |
|---|---|---|---|---|
| c:mobile | dev:store | write | history + queued uploads | inferred: recovered graph; source relationship not re-audited |
| f:analyze | f:runCv | call | — | inferred: recovered graph; source relationship not re-audited |
| f:runCv | f:footdown | call | — | inferred: recovered graph; source relationship not re-audited |
| f:runCv | f:predictViaSidecar | call | — | inferred: recovered graph; source relationship not re-audited |
| f:runCv | f:buildCvResult | call | — | inferred: recovered graph; source relationship not re-audited |
| f:buildCvResult | f:filterModelCandidates | call | — | inferred: recovered graph; source relationship not re-audited |
| f:buildCvResult | f:boomRules | call | — | inferred: recovered graph; source relationship not re-audited |
| f:filterModelCandidates | f:filterStripes | call | — | inferred: recovered graph; source relationship not re-audited |
| f:filterStripes | f:isGeom | call | — | inferred: recovered graph; source relationship not re-audited |
| f:runCv | f:sam3Refinement | call | refineWithSam3 | inferred: recovered graph; source relationship not re-audited |
| f:sam3Refinement | f:sam3live | call | — | inferred: recovered graph; source relationship not re-audited |
| f:sam3Refinement | f:checkRules | call | — | inferred: recovered graph; source relationship not re-audited |
| f:analyze | f:finalizeAnalysis | call | — | inferred: recovered graph; source relationship not re-audited |
| f:finalizeAnalysis | f:finalize | call | — | inferred: recovered graph; source relationship not re-audited |
| f:analyze | f:enforce | call | drop crossers | inferred: recovered graph; source relationship not re-audited |
| f:analyze | f:crossing | call | geometryGuard | inferred: recovered graph; source relationship not re-audited |
| f:runCv | f:metrics | call | — | inferred: recovered graph; source relationship not re-audited |
| f:viaSail | f:chain | call | — | inferred: recovered graph; source relationship not re-audited |
| f:viaSail | f:sailAnalysis | call | — | inferred: recovered graph; source relationship not re-audited |
| f:chain | f:st_boom | call | 3 | inferred: recovered graph; source relationship not re-audited |
| f:chain | f:st_edge | call | 4 | inferred: recovered graph; source relationship not re-audited |
| f:chain | f:st_sam3 | call | 5 | inferred: recovered graph; source relationship not re-audited |
| f:chain | f:finalize | call | 6 | inferred: recovered graph; source relationship not re-audited |
| f:st_finder | f:selectModelStripes | call | — | inferred: recovered graph; source relationship not re-audited |
| f:selectModelStripes | f:runCv | call | runCvInner | inferred: recovered graph; source relationship not re-audited |
| f:st_finder | f:enforce | call | — | inferred: recovered graph; source relationship not re-audited |
| f:st_edge | f:enforce | call | — | inferred: recovered graph; source relationship not re-audited |
| f:st_sam3 | f:enforce | call | — | inferred: recovered graph; source relationship not re-audited |
| f:st_sam3 | f:guardSam3 | call | — | inferred: recovered graph; source relationship not re-audited |
| f:st_sam3 | f:sam3refineSL | call | — | inferred: recovered graph; source relationship not re-audited |
| f:sailAnalysis | f:checkAll | call | 2nd check | inferred: recovered graph; source relationship not re-audited |
| f:sailAnalysis | f:labelMetrics | call | — | inferred: recovered graph; source relationship not re-audited |
| f:finalize | f:postClip | call | — | inferred: recovered graph; source relationship not re-audited |
| f:finalize | f:repair | call | — | inferred: recovered graph; source relationship not re-audited |
| f:finalize | f:checkAll | call | — | inferred: recovered graph; source relationship not re-audited |
| f:repair | f:checkAll | call | — | inferred: recovered graph; source relationship not re-audited |
| f:checkAll | f:isGeom | call | — | inferred: recovered graph; source relationship not re-audited |
| f:checkAll | f:crossing | call | — | inferred: recovered graph; source relationship not re-audited |
| f:seedCache | f:enforce | call | — | inferred: recovered graph; source relationship not re-audited |
| f:seedCache | r2:sam3-seeds/ | write | — | inferred: recovered graph; source relationship not re-audited |
| f:seedCache | f:sam3live | call | — | inferred: recovered graph; source relationship not re-audited |
| f:reconcile | f:recordViolation | call | — | inferred: recovered graph; source relationship not re-audited |
| f:recordViolation | sql:violated_rules | write | — | inferred: recovered graph; source relationship not re-audited |
| f:reconcile | f:saveScanAnalysis | call | — | inferred: recovered graph; source relationship not re-audited |
| f:reconcile | sql:scan_correlations | read | — | inferred: recovered graph; source relationship not re-audited |
| f:saveScanAnalysis | sql:scan_analyses | write | — | inferred: recovered graph; source relationship not re-audited |
| f:ratingStore | fs:rating | write | — | inferred: recovered graph; source relationship not re-audited |
| f:verify | s:sam3verify | http | — | inferred: recovered graph; source relationship not re-audited |
| f:verify | sql:scan_verifications | write | — | inferred: recovered graph; source relationship not re-audited |
| f:predictViaSidecar | s:sidecar | http | /predict-coords | inferred: recovered graph; source relationship not re-audited |
| f:footdown | s:sidecar | http | /find-bottom | inferred: recovered graph; source relationship not re-audited |
| f:st_bottom | s:sidecar | http | /find-bottom | inferred: recovered graph; source relationship not re-audited |
| f:st_boom | s:sidecar | http | /boom-only | inferred: recovered graph; source relationship not re-audited |
| f:st_edge | s:sidecar | http | /edge-snap | inferred: recovered graph; source relationship not re-audited |
| f:sam3refineSL | s:sam3sync | http | — | inferred: recovered graph; source relationship not re-audited |
| f:sam3live | s:sam3sync | http | serverless | inferred: recovered graph; source relationship not re-audited |
| f:sam3live | s:sam3pod | http | baseUrl | inferred: recovered graph; source relationship not re-audited |
| f:overlay | r2:overlays/ | write | — | inferred: recovered graph; source relationship not re-audited |
| env:UNIFIED_ANALYZE | f:viaSail | env | =1 | inferred: recovered graph; source relationship not re-audited |
| env:UNIFIED_ANALYZE | f:analyze | env | unset (default) | inferred: recovered graph; source relationship not re-audited |
| env:SAM3_PRODUCTION_ENABLED | f:st_sam3 | env | — | inferred: recovered graph; source relationship not re-audited |
| env:SAM3_PRODUCTION_ENABLED | f:sam3Refinement | env | — | inferred: recovered graph; source relationship not re-audited |
| env:SAM3_REFINE_GUARD | f:guardSam3 | env | — | inferred: recovered graph; source relationship not re-audited |
| env:POST_SAM3_EDGE_CLIP | f:postClip | env | — | inferred: recovered graph; source relationship not re-audited |
| env:RULES_REPAIR | f:repair | env | — | inferred: recovered graph; source relationship not re-audited |
| env:AUTO_FOOT_DOWN | f:footdown | env | — | inferred: recovered graph; source relationship not re-audited |
| env:SHAPE_CHECK_ALWAYS_RESAMPLE | f:isGeom | env | — | inferred: recovered graph; source relationship not re-audited |
| env:INFERENCE_URL | f:predictViaSidecar | env | — | inferred: recovered graph; source relationship not re-audited |
| s:sidecar | py:GET /preview | call | serves | inferred: recovered graph; source relationship not re-audited |
| s:sidecar | py:GET /health | call | serves | inferred: recovered graph; source relationship not re-audited |
| s:sidecar | py:GET /models | call | serves | inferred: recovered graph; source relationship not re-audited |
| s:sidecar | py:POST /predict-coords | call | serves | inferred: recovered graph; source relationship not re-audited |
| s:sidecar | py:POST /edge-snap | call | serves | inferred: recovered graph; source relationship not re-audited |
| s:sidecar | py:POST /boom-only | call | serves | inferred: recovered graph; source relationship not re-audited |
| s:sidecar | py:POST /find-bottom | call | serves | inferred: recovered graph; source relationship not re-audited |
| py:POST /predict-coords | py:toppers | call | — | inferred: recovered graph; source relationship not re-audited |
| env:TOPPER / toppers | py:toppers | env | — | inferred: recovered graph; source relationship not re-audited |
| env:EDGE_SNAP_EXTEND | py:POST /edge-snap | env | — | inferred: recovered graph; source relationship not re-audited |
| py:POST /predict-coords | r2:models/ | read | weights | inferred: recovered graph; source relationship not re-audited |
| s:preview | py:GET /models | call | same app | inferred: recovered graph; source relationship not re-audited |
| s:preview | py:POST /predict-coords | call | model=<name> | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/scans/:photoId/verification | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/scans/:photoId/verification | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/predict-coords | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/app.py | ep:POST /api/predict-coords | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/predict-coords | f:analyze | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/predict-coords | f:finalize | call | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/analyze | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/smoke/server.sh | ep:POST /api/analyze | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/scripts/check-no-pipeline-duplication.js | ep:POST /api/analyze | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/app.py | ep:POST /api/analyze | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/auto-retrain.sh | ep:POST /api/analyze | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/boom_gallery_fetch.mjs | ep:POST /api/analyze | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/classify-north-sail-types.mjs | ep:POST /api/analyze | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/analyze | f:chain | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/analyze | fs:rating | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/analyze | sql:scan_verifications | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/model-preview | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/model-preview | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/cape31_baseline_sweep.mjs | ep:POST /api/model-preview | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/prod_baseline_fetch.mjs | ep:POST /api/model-preview | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/model-preview | f:analyze | call | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/model-preview/models | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/model-preview/models | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/model-preview/models | s:preview | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/client-errors | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:POST /api/client-errors | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/errors/recent | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/signup-ntfy-poller.mjs | ep:GET /api/errors/recent | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/scripts/error-alert-poller.sh | ep:GET /api/errors/recent | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/labels/:photoId/pending-corrections | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/labels/:photoId/pending-corrections | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/labels/:photoId/pending-corrections | r2:north-images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/labels | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:POST /api/labels | http | — | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/labels | http | — | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:POST /api/labels | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/train.py | ep:POST /api/labels | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/train_boom.py | ep:POST /api/labels | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/rating-cf/public/app.js | ep:POST /api/labels | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/labels | f:overlay | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/labels | r2:images/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/labels | r2:labels/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/labels | r2:overlays/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/labels | r2:north-images/ | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/ai-corrections/pending | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/ai-corrections/pending | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/ai-corrections/pending | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/ai-corrections/:photoId/review | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/ai-corrections/:photoId/review | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/ai-corrections/:photoId/review | f:overlay | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/ai-corrections/:photoId/review | r2:images/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/ai-corrections/:photoId/review | r2:overlays/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/ai-corrections/:photoId/review | r2:sail-ratings/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/ai-corrections/:photoId/review | r2:north-images/ | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/admin/user-corrections | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/admin/user-corrections | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/admin/user-corrections | r2:sail-ratings/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/admin/user-corrections/:photoId/decision | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/admin/user-corrections/:photoId/decision | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/admin/user-corrections/:photoId/decision | r2:labels/ | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/photos | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:POST /api/photos | http | — | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/photos | http | — | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:POST /api/photos | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/smoke/server.sh | ep:POST /api/photos | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/scripts/llm-orientation-pass.mjs | ep:POST /api/photos | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/scripts/orientation-flagged-sheet.mjs | ep:POST /api/photos | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/scripts/orientation-full.mjs | ep:POST /api/photos | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/scripts/reflag-seeds.mjs | ep:POST /api/photos | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/scripts/rules-census.mjs | ep:POST /api/photos | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/photos | s:sidecar | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/photos | r2:images/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/photos | sql:users/sessions/devices | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:PATCH /api/photos/:photoId/details | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:PATCH /api/photos/:photoId/details | http | — | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:PATCH /api/photos/:photoId/details | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/scan-details/presets | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:GET /api/scan-details/presets | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/photos/mine | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/photos/mine | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/mine | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/scans/mine | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:GET /api/scans/mine | http | — | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/scans/mine | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/scans/mine | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/photos/unlabeled | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/photos/unlabeled | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/scripts/llm-orientation-pass.mjs | ep:GET /api/photos/unlabeled | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/scripts/orientation-full.mjs | ep:GET /api/photos/unlabeled | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/scripts/reflag-seeds.mjs | ep:GET /api/photos/unlabeled | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/scripts/rules-census.mjs | ep:GET /api/photos/unlabeled | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/experiments/boomcam-rules-audit-sail149-2/rule_gate.py | ep:GET /api/photos/unlabeled | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/fresh100_blind.mjs | ep:GET /api/photos/unlabeled | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/unlabeled | r2:sail-ratings/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/review-batches | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/review-batches | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/review-batches/boom-cam | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/review-batches/boom-cam | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/experiments/boomcam-rules-audit-sail149-2/rule_gate.py | ep:GET /api/review-batches/boom-cam | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/review-batches/boom-cam/test-sample | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/review-batches/boom-cam/test-sample | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/review-batches | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/review-batches | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/review-batches/:id/sample | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/review-batches/:id/sample | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/review-batches/:id/sample | f:analyze | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/review-batches/:id/sample | r2:images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/photos/:photoId/flag | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:POST /api/photos/:photoId/flag | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/photos/:photoId/discard | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/photos/:photoId/discard | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/photos/flags | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/flags | f:analyze | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/flags | f:recordViolation | call | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/violated-rules | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/violated-rules/:photoId/resolve | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/violated-rules/:photoId/flag | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/photos/:photoId/predict | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:GET /api/photos/:photoId/predict | http | — | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/photos/:photoId/predict | http | — | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/photos/:photoId/predict | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/scripts/reflag-seeds.mjs | ep:GET /api/photos/:photoId/predict | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/scripts/rules-census.mjs | ep:GET /api/photos/:photoId/predict | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/scripts/tune-offsail-k.mjs | ep:GET /api/photos/:photoId/predict | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/:photoId/predict | f:analyze | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/:photoId/predict | f:checkAll | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/:photoId/predict | f:finalize | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/:photoId/predict | r2:images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/:photoId/predict | r2:north-images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/qc/stage/:name | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/qc/stage/:name | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/qc/stage/:name | f:chain | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/qc/stage/:name | f:enforce | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/qc/stage/:name | f:checkAll | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/qc/stage/:name | f:labelMetrics | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/qc/stage/:name | s:sidecar | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/qc/stage/:name | r2:images/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/qc/stage/:name | r2:labels/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/qc/stage/:name | r2:north-images/ | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/sam3-seeds/precompute | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/sam3-seeds/precompute/status | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/sam3-seeds/precompute/status | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/labels/boomless | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/labels/boomless | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/labels/boomless | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/labels/sam3-disagreement-queue | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/sam3_qc_rank_export.mjs | ep:GET /api/labels/sam3-disagreement-queue | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/labels/sam3-disagreement-queue | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/labels/:photoId/boom | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/labels/:photoId/boom | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/labels/:photoId/boom | r2:labels/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/labels/:photoId/boom | r2:sail-ratings/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/labels/:photoId/boom | r2:north-images/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/labels/:photoId/boom | sql:users/sessions/devices | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/sail-ratings/unrated | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/sail-ratings/unrated | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/sail-ratings/unrated | r2:sail-ratings/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/sail-ratings/:id/lines | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/sail-ratings/:id/lines | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/sail-ratings/:id/lines | f:enforce | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/sail-ratings/:id/lines | r2:sail-ratings/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/sail-ratings/:id/lines | r2:north-images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/sail-ratings/excluded | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/auto-retrain.sh | ep:GET /api/sail-ratings/excluded | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/fetch-exclusions.mjs | ep:GET /api/sail-ratings/excluded | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/retrain-local.sh | ep:GET /api/sail-ratings/excluded | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/train.py | ep:GET /api/sail-ratings/excluded | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/sail-ratings/excluded | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/sail-ratings/excluded | r2:sail-ratings/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/sail-ratings/excluded | r2:north-images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/sail-ratings/relabel | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/sail-ratings/relabel | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/sail-ratings/relabel | r2:sail-ratings/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/sail-ratings/:id | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/sail-ratings/:id | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/auto-retrain.sh | ep:POST /api/sail-ratings/:id | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/fetch-exclusions.mjs | ep:POST /api/sail-ratings/:id | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/retrain-local.sh | ep:POST /api/sail-ratings/:id | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/train.py | ep:POST /api/sail-ratings/:id | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/sail-ratings/:id | r2:sail-ratings/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/sail-ratings/:id | r2:north-images/ | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/sail-ratings/:id/discard | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/sail-ratings/:id/discard | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/sail-ratings/:id/discard | r2:labels/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/sail-ratings/:id/discard | r2:sail-ratings/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/sail-ratings/:id/discard | r2:north-images/ | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/sam-edge-ratings | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/sam-edge-ratings | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/sam-edge-ratings/:id | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/sam-edge-ratings/:id | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/gate0-ratings | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/gate0-audit-gallery/index.html | ep:GET /api/gate0-ratings | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/gate0_render_audit_gallery.py | ep:GET /api/gate0-ratings | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/gate0-ratings/:id | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/gate0-audit-gallery/index.html | ep:POST /api/gate0-ratings/:id | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/gate0_render_audit_gallery.py | ep:POST /api/gate0-ratings/:id | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/matrix-notes | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/matrix-notes/:rowId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/matrix-notes/:rowId | f:analyze | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/matrix-notes/:rowId | r2:labels/ | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/model-votes/batch | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/model-votes/batch | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/model-votes/batch | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/model-votes/:photoId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/model-votes/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/model-votes/tally | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/model-votes/tally | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/instrument-photos | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:POST /api/instrument-photos | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/instrument-photos/:id | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:GET /api/instrument-photos/:id | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/instrument-photos/:id | r2:images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/instrument-photos/:id | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/instrument-photos/:id | r2:spinnaker-* | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/spinnaker/photos | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/spinnaker/photos | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/spinnaker/photos | r2:spinnaker-* | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/spinnaker/unlabeled | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/spinnaker/unlabeled | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/spinnaker/unlabeled | s:sidecar | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/spinnaker/unlabeled | r2:spinnaker-* | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/spinnaker/photos/:id/predict | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/spinnaker/photos/:id/predict | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/spinnaker/photos/:id/predict | r2:spinnaker-* | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/spinnaker/predict | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/app.py | ep:POST /api/spinnaker/predict | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/train_spinnaker.py | ep:POST /api/spinnaker/predict | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/spinnaker/predict | r2:spinnaker-* | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/spinnaker/photos/:id | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/spinnaker/photos/:id | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/spinnaker/photos/:id | r2:spinnaker-* | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/spinnaker/labels | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/spinnaker/labels | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/spinnaker/labels | r2:spinnaker-* | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/recommendations/recent | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/access/summary | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/photos/:photoId/overlay | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/photos/:photoId/overlay | http | — | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/photos/:photoId/overlay | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/smoke/server.sh | ep:GET /api/photos/:photoId/overlay | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/:photoId/overlay | f:overlay | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/:photoId/overlay | r2:images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/:photoId/overlay | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/:photoId/overlay | r2:overlays/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/:photoId/overlay | r2:north-images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/photos/:photoId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:GET /api/photos/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/photos/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/photos/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/scripts/llm-orientation-pass.mjs | ep:GET /api/photos/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/scripts/orientation-flagged-sheet.mjs | ep:GET /api/photos/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/scripts/orientation-full.mjs | ep:GET /api/photos/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/scripts/reflag-seeds.mjs | ep:GET /api/photos/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/scripts/rules-census.mjs | ep:GET /api/photos/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/experiments/boomcam-rules-audit-sail149-2/rule_gate.py | ep:GET /api/photos/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/:photoId | r2:images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/:photoId | r2:north-images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/photos/:photoId/thumb | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:GET /api/photos/:photoId/thumb | http | — | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/photos/:photoId/thumb | http | — | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/photos/:photoId/thumb | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/:photoId/thumb | r2:images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/:photoId/thumb | r2:overlays/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/:photoId/thumb | r2:north-images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/labels/stats | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/auto-loop/lib/trigger.mjs | ep:GET /api/labels/stats | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/auto-loop/loop.mjs | ep:GET /api/labels/stats | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/auto-retrain.sh | ep:GET /api/labels/stats | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/labels/stats | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/labels/list | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/labels/list | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/smoke/server.sh | ep:GET /api/labels/list | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/auto-retrain.sh | ep:GET /api/labels/list | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/rating-cf/public/app.js | ep:GET /api/labels/list | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/labels/list | f:labelMetrics | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/labels/list | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/labels/:photoId/metrics | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/labels/:photoId/metrics | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/rating-cf/public/app.js | ep:GET /api/labels/:photoId/metrics | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/labels/:photoId/metrics | f:labelMetrics | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/labels/:photoId/metrics | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/labels/:photoId/metrics | r2:north-images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/labels/:photoId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/labels/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/smoke/server.sh | ep:GET /api/labels/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/auto-loop/lib/trigger.mjs | ep:GET /api/labels/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/auto-loop/loop.mjs | ep:GET /api/labels/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/auto-retrain.sh | ep:GET /api/labels/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/sam3_qc_rank_export.mjs | ep:GET /api/labels/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/rating-cf/public/app.js | ep:GET /api/labels/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/labels/:photoId | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/labels/:photoId | r2:north-images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:DELETE /api/labels/:photoId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:DELETE /api/labels/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/smoke/server.sh | ep:DELETE /api/labels/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/auto-loop/lib/trigger.mjs | ep:DELETE /api/labels/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/auto-loop/loop.mjs | ep:DELETE /api/labels/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/auto-retrain.sh | ep:DELETE /api/labels/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/sam3_qc_rank_export.mjs | ep:DELETE /api/labels/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/rating-cf/public/app.js | ep:DELETE /api/labels/:photoId | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:DELETE /api/labels/:photoId | r2:labels/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:DELETE /api/labels/:photoId | r2:north-images/ | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/boats | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/smoke/server.sh | ep:GET /api/boats | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/boats/:name/sails | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/crossover | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/crossover/validate | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/crossover/suggest | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/compare | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/recommendations | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/recommendations | fs:rating | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/debug-images | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/debug-images | r2:images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/rating/items | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:server/rating-ui/app.js | ep:GET /api/rating/items | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/rating-cf/functions/api/rating/items.js | ep:GET /api/rating/items | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/rating-cf/public/app.js | ep:GET /api/rating/items | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/rating/items | fs:rating | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/rating/:id | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:server/rating-ui/app.js | ep:POST /api/rating/:id | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/rating-cf/functions/api/rating/items.js | ep:POST /api/rating/:id | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/rating-cf/functions/api/rating/upload.js | ep:POST /api/rating/:id | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/rating-cf/public/app.js | ep:POST /api/rating/:id | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/rating/:id | fs:rating | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/rating/rerun/:id | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/rating/rerun/:id | fs:rating | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/rating/rerun-all | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/rating/rerun-all | fs:rating | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /ping | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/smoke/server.sh | ep:GET /ping | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/boom_gallery_suite.sh | ep:GET /ping | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/holdout_suite.sh | ep:GET /ping | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/oracle_dump.sh | ep:GET /ping | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/pod-finder-moredata.sh | ep:GET /ping | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /ping | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /ping | r2:sail-ratings/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/auth/register | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:POST /api/auth/register | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/auth/register | sql:users/sessions/devices | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/auth/transfer/generate | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/auth/transfer/claim | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/auth/transfer/claim | sql:users/sessions/devices | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/auth/signup | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:POST /api/auth/signup | http | — | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/auth/signup | http | — | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:POST /api/auth/signup | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/auth/signup | sql:users/sessions/devices | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/auth/login | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:POST /api/auth/login | http | — | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/auth/login | http | — | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:POST /api/auth/login | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/auth/login | sql:users/sessions/devices | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/auth/forgot | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:POST /api/auth/forgot | http | — | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/auth/forgot | http | — | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:POST /api/auth/forgot | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/auth/reset | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:POST /api/auth/reset | http | — | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/auth/reset | http | — | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:POST /api/auth/reset | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/auth/reset | sql:users/sessions/devices | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/auth/logout | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:POST /api/auth/logout | http | — | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/auth/logout | http | — | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:POST /api/auth/logout | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/auth/me | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:GET /api/auth/me | http | — | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/auth/me | http | — | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/auth/me | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/smoke/contract.mjs | ep:GET /api/auth/me | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/smoke/server.sh | ep:GET /api/auth/me | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/auth/signups/recent | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/signup-ntfy-poller.mjs | ep:GET /api/auth/signups/recent | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/scripts/error-alert-poller.sh | ep:GET /api/auth/signups/recent | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/auth/signups/recent | sql:users/sessions/devices | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/auth/chat-signups/recent | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/auth/chat-signups/recent | sql:users/sessions/devices | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/auth/chat-signups/rejected | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/auth/chat-signups/:eventId/decision | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/auth/chat-signups/:eventId/decision | sql:users/sessions/devices | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/auth/users | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/auth/users | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/auth/users | sql:users/sessions/devices | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/auth/settings | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:GET /api/auth/settings | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:PATCH /api/auth/settings/ai-rate-limits | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:PATCH /api/auth/settings/auto-approval | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:PATCH /api/auth/settings/auto-approval | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:PUT /api/auth/settings/preapproved-emails | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:PUT /api/auth/settings/preapproved-emails | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/auth/users/:id/approve | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/auth/users/:id/approve | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/auth/users/:id/approve | sql:users/sessions/devices | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/auth/users/:id/disable | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:POST /api/auth/users/:id/disable | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/auth/users/:id/disable | sql:users/sessions/devices | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/auth/access-log | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/auth/access-log | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/auth/access-log | sql:users/sessions/devices | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/feedback | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:POST /api/feedback | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/profile | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/profile | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:PATCH /api/profile | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:PATCH /api/profile | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:PATCH /api/profile | sql:users/sessions/devices | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/teams | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/teams | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/teams/:id/invite | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/teams/join | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:DELETE /api/teams/:id/members/:userId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:DELETE /api/teams/:id | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/teams/:id/analyses | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/teams/:id/analyses | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/accounts | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/doyle-live-smoke.mjs | ep:GET /api/accounts | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/smoke/server.sh | ep:GET /api/accounts | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/accounts | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:POST /api/accounts | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/doyle-live-smoke.mjs | ep:POST /api/accounts | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/smoke/server.sh | ep:POST /api/accounts | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/accounts/join | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:POST /api/accounts/join | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/accounts/:id | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:PATCH /api/accounts/:id | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:PATCH /api/accounts/:id | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:PATCH /api/accounts/:id/brand | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:PATCH /api/accounts/:id/brand | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:DELETE /api/accounts/:id | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:DELETE /api/accounts/:id | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/members | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/accounts/:id/members | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/accounts/:id/members | sql:users/sessions/devices | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/invites | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/accounts/:id/invites | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/accounts/:id/invites | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:POST /api/accounts/:id/invites | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:DELETE /api/accounts/:id/invites/:code | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:DELETE /api/accounts/:id/invites/:code | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:PATCH /api/accounts/:id/members/:userId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:PATCH /api/accounts/:id/members/:userId | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:DELETE /api/accounts/:id/members/:userId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:DELETE /api/accounts/:id/members/:userId | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/audit | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/accounts/:id/audit | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/accounts/:id/audit | sql:users/sessions/devices | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/boats | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/accounts/:id/boats | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/accounts/:id/boats | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:POST /api/accounts/:id/boats | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/boats/:boatId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:PATCH /api/accounts/:id/boats/:boatId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:DELETE /api/accounts/:id/boats/:boatId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/boats/:boatId/sails | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/accounts/:id/boats/:boatId/sails | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/accounts/:id/boats/:boatId/sails | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:POST /api/accounts/:id/boats/:boatId/sails | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/sails/:sailId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:PATCH /api/accounts/:id/sails/:sailId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:DELETE /api/accounts/:id/sails/:sailId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/sessions | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/accounts/:id/sessions | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/accounts/:id/sessions | sql:users/sessions/devices | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/accounts/:id/sessions | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:POST /api/accounts/:id/sessions | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/accounts/:id/sessions | sql:users/sessions/devices | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/sessions/:sessionId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/accounts/:id/sessions/:sessionId | sql:users/sessions/devices | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/sessions/:sessionId/report | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/accounts/:id/sessions/:sessionId/report | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/accounts/:id/sessions/:sessionId/report | sql:users/sessions/devices | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:PATCH /api/accounts/:id/sessions/:sessionId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:PATCH /api/accounts/:id/sessions/:sessionId | sql:users/sessions/devices | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:DELETE /api/accounts/:id/sessions/:sessionId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:DELETE /api/accounts/:id/sessions/:sessionId | sql:scan_analyses | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:DELETE /api/accounts/:id/sessions/:sessionId | sql:users/sessions/devices | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/scans | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/accounts/:id/scans | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/accounts/:id/scans/:scanId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:POST /api/accounts/:id/scans/:scanId | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/accounts/:id/scans/:scanId | r2:labels/ | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/scans/:scanId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/accounts/:id/scans/:scanId | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:PATCH /api/accounts/:id/scans/:scanId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:PATCH /api/accounts/:id/scans/:scanId | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:DELETE /api/accounts/:id/scans/:scanId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:DELETE /api/accounts/:id/scans/:scanId | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/scans/:scanId/photo | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/accounts/:id/scans/:scanId/photo | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/accounts/:id/scans/:scanId/photo | r2:images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/accounts/:id/scans/:scanId/photo | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/scans/:scanId/overlay | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/accounts/:id/scans/:scanId/overlay | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/accounts/:id/scans/:scanId/overlay | r2:images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/accounts/:id/scans/:scanId/overlay | r2:overlays/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/scans/:scanId/thumb | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/accounts/:id/scans/:scanId/thumb | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/accounts/:id/scans/:scanId/thumb | r2:images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/scans/:scanId/metrics | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/accounts/:id/scans/:scanId/metrics | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/accounts/:id/scans/:scanId/metrics | f:labelMetrics | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/accounts/:id/scans/:scanId/metrics | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/upload-links | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/accounts/:id/upload-links | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/accounts/:id/upload-links | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:POST /api/accounts/:id/upload-links | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:DELETE /api/accounts/:id/upload-links/:token | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:DELETE /api/accounts/:id/upload-links/:token | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /u/:token | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /u/:token | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/.venv/lib/python3.11/site-packages/sympy/polys/polyroots.py | ep:GET /u/:token | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/.venv/lib/python3.11/site-packages/transformers/modeling_rope_utils.py | ep:GET /u/:token | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/gate1-deeplsd-work/.venv-deeplsd/lib/python3.14/site-packages/sympy/polys/polyroots.py | ep:GET /u/:token | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/upload-links/:token/photos | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/upload-links/:token/photos | f:analyze | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/upload-links/:token/photos | r2:images/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/upload-links/:token/photos | sql:scan_analyses | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/boats/:boatId/crew | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:PATCH /api/accounts/:id/boats/:boatId/privacy | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/accounts/:id/boats/:boatId/invites | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/accounts/:id/boat-invites/:token/accept | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/accounts/:id/boat-invites/:token/accept | sql:users/sessions/devices | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:PATCH /api/accounts/:id/boats/:boatId/crew/:userId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:DELETE /api/accounts/:id/boats/:boatId/crew/:userId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:DELETE /api/accounts/:id/boats/:boatId/crew/:userId | sql:users/sessions/devices | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/scans/:scanId/comments | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/accounts/:id/scans/:scanId/comments | sql:users/sessions/devices | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/accounts/:id/scans/:scanId/comments | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/boat-metrics | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/accounts/:id/boat-metrics | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/accounts/:id/boat-metrics | sql:users/sessions/devices | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/accounts/:id/sails/:sailId/targets | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/accounts/:id/sails/:sailId/targets | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/accounts/:id/sails/:sailId/targets | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:POST /api/accounts/:id/sails/:sailId/targets | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/tenant | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/tenant | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/smoke/server.sh | ep:GET /api/tenant | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/admin/tenant-domains | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:DELETE /api/admin/tenant-domains/:hostname | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/doyle-demo/session | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/doyle-live-smoke.mjs | ep:GET /api/doyle-demo/session | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/doyle-demo/session | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/doyle-live-smoke.mjs | ep:POST /api/doyle-demo/session | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:DELETE /api/doyle-demo/session | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/doyle-live-smoke.mjs | ep:DELETE /api/doyle-demo/session | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:DELETE /api/doyle-demo/session | sql:users/sessions/devices | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/doyle-demo/sails/:id/reference | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/doyle-live-smoke.mjs | ep:GET /api/doyle-demo/sails/:id/reference | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:PUT /api/doyle-demo/sails/:id/reference | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/doyle-live-smoke.mjs | ep:PUT /api/doyle-demo/sails/:id/reference | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/doyle-demo | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/doyle-demo | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/doyle-live-smoke.mjs | ep:GET /api/doyle-demo | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/scans/:photoId/analysis | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:GET /api/scans/:photoId/analysis | http | — | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/scans/:photoId/analysis | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/scans/:photoId/analysis | r2:images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/scans/:photoId/analysis | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/scans/:photoId/analysis | r2:overlays/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/scans/:photoId/analysis | r2:north-images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/scans/:photoId/export-image | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:GET /api/scans/:photoId/export-image | http | — | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/scans/:photoId/export-image | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/scans/:photoId/export-image | f:overlay | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/scans/:photoId/export-image | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/scans/:photoId/export.jpg | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/scans/:photoId/export.jpg | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/scans/:photoId/export.pdf | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/scans/:photoId/export.pdf | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/scans/:photoId/export.pdf | f:analyze | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/scans/:photoId/export.pdf | f:metrics | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/scans/:photoId/export.pdf | r2:images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/scans/:photoId/export.pdf | r2:north-images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/scans/:photoId/export.pdf | sql:scan_analyses | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/scans/:photoId/sail-type | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:POST /api/scans/:photoId/sail-type | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/scans/:photoId/sail-type | f:analyze | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/scans/:photoId/sail-type | f:boomRules | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/scans/:photoId/sail-type | f:labelMetrics | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/scans/:photoId/sail-type | f:metrics | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/scans/:photoId/sail-type | r2:labels/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/scans/:photoId/sail-type | sql:scan_analyses | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/scans/:photoId/sail-life | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/scans/:photoId/sail-life | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/scans/:photoId/sail-life | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/model-runs | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/auto-retrain.sh | ep:GET /api/model-runs | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/holdout_suite.sh | ep:GET /api/model-runs | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/report-model-run.mjs | ep:GET /api/model-runs | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/retrain-local.sh | ep:GET /api/model-runs | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/model-runs | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/auto-retrain.sh | ep:POST /api/model-runs | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/holdout_suite.sh | ep:POST /api/model-runs | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/report-model-run.mjs | ep:POST /api/model-runs | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/retrain-local.sh | ep:POST /api/model-runs | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/feed | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:GET /api/feed | http | — | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:GET /api/feed | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/smoke/server.sh | ep:GET /api/feed | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/feed | sql:users/sessions/devices | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/feed | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:POST /api/feed | http | — | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:POST /api/feed | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:scripts/smoke/server.sh | ep:POST /api/feed | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/feed | f:labelMetrics | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/feed | r2:labels/ | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:DELETE /api/feed/:postId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| c:mobile | ep:DELETE /api/feed/:postId | http | — | inferred: recovered graph; source relationship not re-audited |
| c:desktop | ep:DELETE /api/feed/:postId | http | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/feed/:postId/photo | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/feed/:postId/photo | r2:images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/feed/:postId/overlay | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/feed/:postId/overlay | r2:images/ | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/feed/:postId/overlay | r2:overlays/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/model-ranking/default | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/model-ranking/batch | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/model-ranking/batches | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:PUT /api/model-ranking/batches/:batchId/votes/:photoId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/model-ranking/predict | call | mounts | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:GET /api/blind-ratings/:batch | call | mounts | inferred: recovered graph; source relationship not re-audited |
| sc:server/inference/blind_rating_unblind.mjs | ep:GET /api/blind-ratings/:batch | http | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/blind-ratings/:batch | r2:blind-ratings/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:POST /api/blind-ratings/:batch/:pairId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/blind-ratings/:batch/:pairId | r2:blind-ratings/ | write | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:DELETE /api/blind-ratings/:batch/:pairId | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:DELETE /api/blind-ratings/:batch/:pairId | r2:blind-ratings/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/analyze | f:recs | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/analyze | f:ratingStore | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/analyze | f:verify | call | fire-and-forget | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/analyze | sql:scan_correlations | write | clientScanId | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/photos | f:reconcile | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/labels | f:labelMetrics | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/labels | f:saveScanAnalysis | call | saveLabelAnalysisSnapshot | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/:photoId/predict | f:seedCache | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/:photoId/predict | r2:predictions/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/:photoId/predict | f:chain | call | sail-pipeline seed | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/scans/:photoId/sail-type | f:saveScanAnalysis | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/upload-links/:token/photos | f:saveScanAnalysis | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/violated-rules | sql:violated_rules | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/violated-rules/:photoId/flag | sql:violated_rules | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/model-runs | sql:model_runs | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/sam3-seeds/precompute | f:chain | call | — | inferred: recovered graph; source relationship not re-audited |
| ep:POST /api/instrument-photos | r2:instrument-images/ | write | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/scans/:photoId/analysis | sql:scan_analyses | read | — | inferred: recovered graph; source relationship not re-audited |
| ep:GET /api/photos/:photoId/thumb | r2:thumbs/ | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:USE /rating (static rating-ui) | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:USE /rating (static rating-ui) | fs:rating | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:USE /rating-images (static, labelAuth) | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:USE /rating-images (static, labelAuth) | fs:rating | read | — | inferred: recovered graph; source relationship not re-audited |
| s:railway | ep:USE /debug-images (static, labelAuth) | call | mounts | inferred: recovered graph; source relationship not re-audited |
| ep:USE /debug-images (static, labelAuth) | fs:rating | read | — | inferred: recovered graph; source relationship not re-audited |
| sc:holdout_suite | ep:POST /api/analyze | http | local server | inferred: recovered graph; source relationship not re-audited |
| sc:holdout_suite | ep:POST /api/model-runs | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:pseudo_label | f:checkAll | call | — | inferred: recovered graph; source relationship not re-audited |
| sc:pseudo_label | fs:training | write | — | inferred: recovered graph; source relationship not re-audited |
| sc:reflag | f:checkAll | call | — | inferred: recovered graph; source relationship not re-audited |
| sc:reflag | r2:sam3-seeds/ | read | — | inferred: recovered graph; source relationship not re-audited |
| sc:unblind | r2:blind-ratings/ | read | — | inferred: recovered graph; source relationship not re-audited |
| sc:sam3warm | s:sam3sync | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:train | fs:training | read | — | inferred: recovered graph; source relationship not re-audited |
| sc:train | r2:labels/ | read | — | inferred: recovered graph; source relationship not re-audited |
| sc:train | ep:GET /api/sail-ratings/excluded | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:train | r2:models/ | write | upload-model | inferred: recovered graph; source relationship not re-audited |
| sc:harvest | s:north | http | — | inferred: recovered graph; source relationship not re-audited |
| sc:harvest | fs:training | write | — | inferred: recovered graph; source relationship not re-audited |
| sc:backup | r2:winners/ backups/ training | write | — | inferred: recovered graph; source relationship not re-audited |
| c:blind | ep:GET /api/blind-ratings/:batch | http | — | inferred: recovered graph; source relationship not re-audited |
| c:blind | ep:POST /api/blind-ratings/:batch/:pairId | http | — | inferred: recovered graph; source relationship not re-audited |
| s:cfpages | c:labeler | call | hosts | inferred: recovered graph; source relationship not re-audited |
| s:cfpages | c:site | call | hosts | inferred: recovered graph; source relationship not re-audited |
| s:cfpages | c:galleries | call | hosts | inferred: recovered graph; source relationship not re-audited |
| s:cfpages | c:desktop | call | hosts | inferred: recovered graph; source relationship not re-audited |
| c:labeler | ep:GET /api/model-ranking/default | http | active labeler caller | verified: labeler/web/src/lib/modelRanking.ts; ModelRankingPage.tsx |
| c:labeler | ep:GET /api/model-ranking/batch | http | active labeler caller | verified: labeler/web/src/lib/modelRanking.ts; ModelRankingPage.tsx |
| c:labeler | ep:POST /api/model-ranking/batches | http | active labeler caller | verified: labeler/web/src/lib/modelRanking.ts; ModelRankingPage.tsx |
| c:labeler | ep:PUT /api/model-ranking/batches/:batchId/votes/:photoId | http | active labeler caller | verified: labeler/web/src/lib/modelRanking.ts; ModelRankingPage.tsx |
| c:labeler | ep:POST /api/model-ranking/predict | http | active labeler caller | verified: labeler/web/src/lib/modelRanking.ts; ModelRankingPage.tsx |
| ep:GET /api/model-ranking/batch | sql:model_ranking_* | read | resume batch | verified: server/modelRanking.js latestBatch |
| ep:POST /api/model-ranking/batches | sql:model_ranking_* | write | persist | verified: server/modelRanking.js createBatch/saveVote |
| ep:PUT /api/model-ranking/batches/:batchId/votes/:photoId | sql:model_ranking_* | write | persist | verified: server/modelRanking.js createBatch/saveVote |
| ep:POST /api/model-ranking/batches | s:preview | http | GET /models registry | verified: server/modelRanking.js registeredModels |
| ep:POST /api/model-ranking/predict | s:preview | http | GET /models registry | verified: server/modelRanking.js registeredModels |
| ep:POST /api/model-ranking/predict | f:analyze | call | cache miss: legacy; SAM3 off | verified: server/modelRanking.js:78; server/index.js router injection |
| ep:POST /api/model-ranking/predict | sql:model_ranking_* | read | prediction cache lookup | verified: server/modelRanking.js getPrediction/cachePrediction (also writes on miss) |
| ep:POST /api/model-ranking/predict | r2:images/ | read | cache miss: getPhoto (external IDs use North store) | verified: server/index.js router getPhoto injection |
| ep:GET /api/scans/:photoId/verification | sql:scan_verifications | read | status / correlation lookup | verified: server/index.js verification route; server/scanVerifications.js; server/scanCorrelation.js |
| ep:GET /api/scans/:photoId/verification | sql:scan_correlations | read | status / correlation lookup | verified: server/index.js verification route; server/scanVerifications.js; server/scanCorrelation.js |
| ep:POST /api/analyze | f:viaSail | call | UNIFIED_ANALYZE=1 or true | verified: server/index.js |
| ep:POST /api/analyze | f:analyze | call | otherwise: legacy branch | verified: server/index.js |
| f:viaSail | frame:upright | call | preprocess | verified: server/index.js:2219 |
| frame:upright | f:chain | call | upright input | verified: server/index.js:2232 |
| f:chain | f:st_bottom | call | optional: AUTO_FOOT_DOWN enabled | verified: server/qcStages.js:568 |
| f:st_bottom | f:st_finder | call | rotated pixels + matching W,H | verified: server/qcStages.js:581 |
| f:st_finder | f:st_boom | call | finder failure recorded | verified: server/qcStages.js:604 |
| f:st_boom | f:st_edge | call | if stripes exist | verified: server/qcStages.js:626 |
| f:st_edge | f:st_sam3 | call | optional: SAM3_PRODUCTION_ENABLED=1 | verified: server/index.js:2238 |
| f:st_sam3 | f:finalizeStripes | call | guard if SAM3_REFINE_GUARD=1; failure retains lines | verified: server/qcStages.js:644 |
| f:st_edge | f:finalizeStripes | call | SAM3 disabled | verified: server/qcStages.js:658 |
| f:finalizeStripes | f:finalizeError | call | on exception | verified: server/qcStages.js finalize catch |
| f:finalizeStripes | f:sailAnalysis | call | chain result | verified: server/index.js:2241 |
| f:finalizeError | f:sailAnalysis | call | continues without finalizer attestation | verified: server/qcStages.js:710 |
| f:sailAnalysis | f:duplicateRules | call | rechecks output | verified: server/sailAnalysis.js:40 |
| f:duplicateRules | frame:footdown | call | customer response | verified: server/sailAnalysis.js:67 |
| f:chain | f:st_finder | call | bottom disabled / fails: original current frame | verified: server/qcStages.js runPrecomputeChain |
| c:mobile | ep:POST /api/analyze | http | capture | verified: src/api.ts |
| c:desktop | ep:POST /api/analyze | http | upload | verified: desktop/src/lib/api.ts |
| proposed:entry | proposed:bottom | call | proposed | proposal: docs/ONE-PIPELINE-PLAN.md; not implemented |
| proposed:bottom | proposed:finder | call | proposed | proposal: docs/ONE-PIPELINE-PLAN.md; not implemented |
| proposed:finder | proposed:select | call | proposed | proposal: docs/ONE-PIPELINE-PLAN.md; not implemented |
| proposed:select | proposed:boom | call | proposed | proposal: docs/ONE-PIPELINE-PLAN.md; not implemented |
| proposed:boom | proposed:edge | call | proposed | proposal: docs/ONE-PIPELINE-PLAN.md; not implemented |
| proposed:edge | proposed:refine | call | proposed | proposal: docs/ONE-PIPELINE-PLAN.md; not implemented |
| proposed:refine | proposed:finalize | call | proposed | proposal: docs/ONE-PIPELINE-PLAN.md; not implemented |
| proposed:finalize | proposed:return | call | proposed | proposal: docs/ONE-PIPELINE-PLAN.md; not implemented |
