snipe/docs/reference/trust-scoring.md
pyr0ball 2dda26a911
Some checks failed
CI / Frontend typecheck + tests (push) Waiting to run
CI / Python tests (push) Waiting to run
Mirror / mirror (push) Has been cancelled
Release / release (push) Has been cancelled
feat: infra/devops batch — CI/CD, installer, nginx docs, cf-orch agent (v0.3.0)
Closes #15, #22, #24, #25. Closes #1 and #27 (already shipped in 0.2.0).

## CI/CD (#22)
- .forgejo/workflows/ci.yml — Python lint (ruff) + pytest + Vue typecheck + vitest
  on every PR/push. Installs cf-core from GitHub mirror for the CI runner.
- .forgejo/workflows/release.yml — Docker build/push (api + web) to Forgejo registry
  on v* tags; git-cliff changelog; multi-arch amd64+arm64.
- .forgejo/workflows/mirror.yml — push to GitHub + Codeberg mirrors.

## Self-hosted installer (#25)
- install.sh rewritten to match CF installer pattern: coloured output, named
  functions, --docker / --bare-metal / --help flags, auto-detect Docker/conda/
  Python/Node/Chromium/Xvfb, license key prompting with format validation.

## Nginx docs (#24)
- docs/nginx-self-hosted.conf — sample nginx config: SPA fallback, SSE proxy
  (proxy_buffering off), long-term asset cache headers.
- docs/getting-started/installation.md — bare-metal install section with nginx
  setup, Chromium/Xvfb note, serve-ui.sh vs nginx trade-off.

## cf-orch agent (#15)
- compose.override.yml — cf-orch-agent sidecar service (profiles: [orch]).
  Starts only with docker compose --profile orch. Registers with coordinator at
  CF_ORCH_COORDINATOR_URL (default 10.1.10.71:7700).
- .env.example — CF_ORCH_URL / CF_ORCH_COORDINATOR_URL comments expanded.

## Docs
- mkdocs.yml + full docs/ tree (getting-started, reference, user-guide) staged
  from prior session work.

Bump version 0.2.0 → 0.3.0.
2026-04-14 06:19:25 -07:00

84 lines
2.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Trust Score Algorithm
## Signal scoring
Each signal contributes 020 points to the composite score.
### account_age
| Days old | Score |
|----------|-------|
| < 7 | 0 (triggers `new_account` hard flag) |
| 730 | 5 |
| 3090 | 10 |
| 90365 | 15 |
| > 365 | 20 |
Data source: eBay profile page (BTF scraper via headed Chromium + Xvfb — eBay API does not expose account registration date).
### feedback_count
| Count | Score |
|-------|-------|
| 0 | 0 (triggers `zero_feedback` hard flag, score capped at 35) |
| 19 | 5 |
| 1049 | 10 |
| 50199 | 15 |
| 200+ | 20 |
### feedback_ratio
| Ratio | Score |
|-------|-------|
| < 80% (with 20+ reviews) | 0 (triggers `established_bad_actor`) |
| < 90% | 5 |
| 9094% | 10 |
| 9598% | 15 |
| 99100% | 20 |
### price_vs_market
Compares listing price to the median of recent completed sales from eBay Marketplace Insights API.
| Price vs. median | Score |
|-----------------|-------|
| < 40% | 0 (triggers `suspicious_price` flag) |
| 4059% | 5 |
| 6079% | 10 |
| 80120% | 20 (normal range) |
| 121149% | 15 |
| 150%+ | 10 |
`suspicious_price` flag is suppressed when the market price distribution is too wide (standard deviation > 50% of median) — this prevents false positives on heterogeneous search results.
When no market data is available, this signal returns `None` and is excluded from the composite.
### category_history
Derived from the seller's recent listing history (categories of their sold items):
| Result | Score |
|--------|-------|
| Seller has history in this category | 20 |
| Seller sells cross-category (generalist) | 10 |
| No category history available | None (excluded from composite) |
## Composite calculation
```
composite = (sum of available signal scores) / (20 × count of available signals) × 100
```
This ensures missing signals don't penalize a seller — only available signals count toward the denominator.
## Zero-feedback cap
When `feedback_count == 0`, the composite is hard-capped at **35** after the standard calculation. A 0-feedback seller cannot score above 35 regardless of other signals.
## Partial scores
A score is marked **partial** when one or more signals are `None` (not yet available). The score is recalculated and the partial flag is cleared when enrichment completes.
## Red flag override
Red flags are evaluated independently of the composite score. A seller can have a high composite score and still trigger red flags — for example, a long-established seller with a suspicious-priced listing and duplicate photos.