Skip to content

docs: sync with sherlock backend changes (status, reason codes, is_banned, dashboard-session list)#4

Merged
maheshpchandran merged 5 commits into
mainfrom
docs/sync-backend-changes
May 20, 2026
Merged

docs: sync with sherlock backend changes (status, reason codes, is_banned, dashboard-session list)#4
maheshpchandran merged 5 commits into
mainfrom
docs/sync-backend-changes

Conversation

@maheshpchandran
Copy link
Copy Markdown
Contributor

Summary

Brings the public docs back in sync with ~14 days of sherlock API-surface changes ahead of cutover. Two waves of edits, two commits.

Wave 1 — drop completed_with_partial and rename 7 reason codes

ScanStatusT in sherlock is now just processing | completed | failed. The partial_reason webhook field went away with it. Scans that experience step failures land in completed with the coverage object recording what was skipped.

Reason-code renames (per aggregator.py and llm_decision.py):

Old New
CONTENT_SAFETY_TEXT_FLAGGED TEXT_FLAGGED
CONTENT_SAFETY_IMAGE_FLAGGED IMAGE_FLAGGED
CONTENT_FILTER_TRIGGERED UNSAFE_CONTENT_BLOCKED
JUDGE_BUMP_UP SECONDARY_REVIEW_CONFIRMED
JUDGE_BUMP_DOWN SECONDARY_REVIEW_DOWNGRADED
LLM_API_ERROR ANALYSIS_ERROR
LLM_PARSE_ERROR PARSE_ERROR

Header note added that codes are an unordered set AND open-ended, so integrators code defensively against unknown codes.

Wave 2 — is_banned, dashboard-session list, 403 wording

  • Get scan: document is_banned (bool | null) at the top level of the scan record. null until evaluated; then true if the upstream platform has banned the creator (404/410/redirect), false if still live.
  • Get scan → Coverage section: rewrites the "coverage is webhook-only" claim — it's also on poll responses, nested at triage_report.coverage. Webhook payload carries the same object at the top level.
  • Create batch: tightens the partial-acceptance worked example so ordering ("first N accepted, last profiles_skipped dropped") is explicit. Worked numbers: 50 URLs submitted with 30 remaining → 30 queued, 20 dropped.
  • Authentication + skill.md: dashboard-session-only list expands from three to five endpoints — POST /org/api-keys and GET /org/api-keys also reject API keys to prevent API-key → API-key chaining.
  • Errors: documents the new 403 detail string for those two endpoints: This endpoint requires a dashboard session. API keys are not permitted.

Wave 3 — policy decisions (out of scope for this PR)

The four advanced PATCH /org/settings fields (llm_decision_chain, judge_chain, llm_max_tokens, judge_max_tokens) and the consolidated daily-quota concept page were considered and intentionally not added — kept the public surface minimal pre-cutover.

Base-branch note

Branched off docs/skill-override (PR #3, still open). Until #3 merges, this PR will show all 5 commits; once #3 lands, only the 2 new commits remain. The base commits in this stack:

  • 8400b4a docs: scrub internal mechanics from scoring and confidence explanations
  • 33cc736 docs: remove usage endpoints from the public surface
  • 18d30c9 docs: ship custom skill.md override to fix autogenerator inaccuracies

Verification

grep -rn 'completed_with_partial\|partial_reason\|dossier_url\|JUDGE_BUMP\|CONTENT_FILTER_TRIGGERED\|CONTENT_SAFETY_TEXT_FLAGGED\|CONTENT_SAFETY_IMAGE_FLAGGED\|LLM_API_ERROR\|LLM_PARSE_ERROR' .

Returns zero hits.

Test plan

  • PR docs: ship custom skill.md to fix autogenerator inaccuracies #3 merges first; this PR collapses to 2 commits
  • Mintlify Cloud preview renders /reference/reason-codes with the seven new codes, no JUDGE_BUMP_* / LLM_*_ERROR rows, header note about open-ended set
  • /reference/status shows three rows (no completed_with_partial)
  • /api/scans/get shows is_banned ResponseField + JSON example; Coverage section says coverage is at triage_report.coverage on polls
  • /api/scans/batch worked example shows 50→30 accepted, 20 skipped, with ordering called out
  • /authentication table has 5 rows, intro says "five management endpoints"
  • /api/errors lists the new 403 string for Create API key / List API keys
  • /webhooks/payload no longer mentions completed_with_partial or partial_reason
  • /skill.md (raw) reflects the same five-endpoint list and is_banned blurb

The Mintlify autogenerator keeps producing skill.md content that
contradicts the source docs — RESTful priors over source content. After
two rounds of strengthening the source pages (adding explicit Notes,
restructuring sections), the same inaccuracies still appear in the
generated /skill.md:

  - Revoke documented as POST .../{key_id}/revoke (actual:
    DELETE .../{key_id})
  - Webhook rotate documented without the /org/ segment
  - "Same as API key" storage analogy applied to the webhook secret
    (which is stored plaintext, not hashed)
  - completed_with_partial surfaced as if active
  - Revoke described as admin-only
  - Confidence triggers condensed inaccurately
  - Usage endpoints omitted

Per Mintlify's spec, a skill.md at the project root overrides
auto-generation. This commit ships that override, written to the
agentskills.io v0 spec (frontmatter + body). Content is grounded in
verified facts from sherlock/src:

  - api/routes_auth.py:254  → /api/v2/org/webhook-secret/rotate
  - api/routes_auth.py:314  → DELETE /api/v2/org/api-keys/{key_id}
  - api/routes_auth.py:318-321,337-338 → revoke role rules
  - db/mongodb.py:513       → webhook_secret stored plaintext
  - services/aggregator.py:499-530 → confidence triggers
  - services/aggregator.py:354 → score band thresholds

Also adds a brief "Organization identifier" section to
authentication.mdx noting that org_id is opaque (no fixed alphabet) —
fixes the org_<hex> hallucination in the previous skill.md.

The override file is 306 lines (well under the 500-line guidance from
the agentskills.io spec).
Usage / analytics endpoints are dashboard-only — they are not part of
the public API contract. Removing them from the published docs so
external customers don't build integrations against them.

- Deleted the four api/usage/*.mdx pages (totals, scans, priority,
  warmer-health) and the empty parent directory.
- Removed the Usage group from docs.json navigation.
- skill.md: dropped the Usage table; added an explicit note that
  usage data is dashboard-only so agents stop hallucinating GET paths.
- dashboard-overview.mdx: the Usage sidebar row now reads
  "Dashboard-only" instead of linking to API pages. Removed the
  "Get usage totals" link from the Home row and reworded the
  role-gating table.
- api/errors.mdx: dropped "or usage endpoints" from the
  Org-settings-not-found row.

Cross-repo follow-up: the corresponding endpoints in
sherlock/src/api/routes_auth.py (get_usage, get_usage_scans,
get_usage_priority, warmer-health) should be gated to dashboard
sessions only — API-key auth on these paths should return 403, to
match the new docs.
User intent: nothing in customer-facing docs should help a reader
reverse-engineer Tumban's detection pipeline. The previous pass
exposed too much — strategy names, judge model, bump_up/bump_down
adjudication, internal score arithmetic.

Scoring (concepts/recommendations.mdx)
- Removed the "three independent detection strategies" paragraph and
  the bump_up/bump_down adjudication detail.
- Replaced with a contract-only explanation: what the score means
  ("confidence a violation is present"), what fields are part of the
  public contract, and that other fields are opaque and may change.

Confidence (concepts/confidence.mdx)
- Removed the exact trigger table that listed blocklist thresholds,
  multi-strategy agreement, contextual-model confidence pass-through,
  and judge invocation.
- Replaced with a semantic table (what high/medium/low mean to a
  reviewer). Kept the "never low when no_flags" gotcha — it's a
  contract-level invariant, not mechanism.

Field surface (api/scans/get.mdx)
- Dropped the ResponseField blocks for strategy_scores and
  judge_model_invoked, removed them from the example JSON, and
  removed the "Strategy scores" bullet from the dashboard section.
  Folded them into the existing "internal, opaque, subject to change"
  disclaimer (which I also generalised — no longer enumerates the
  specific internal fields).

Reason codes (reference/reason-codes.mdx)
- Reworded descriptions that explicitly named the judge model or the
  "contextual model" / classifier internals. Codes themselves
  (JUDGE_BUMP_UP, LLM_API_ERROR, etc.) are left literal because the
  API emits them verbatim — cross-repo follow-up below.
- Stripped the source-trail MDX comment that cited
  aggregator.py:_aggregate_reason_codes and strategies/llm_decision.py.

Cross-doc cleanup
- evidence-index, scans/get, webhooks/payload: replaced
  "the contextual model cited" wording with "Tumban cited".
- index.mdx: removed "multi-strategy detection pipeline".
- skill.md: rewrote Confidence and Score-band sections to match the
  scrubbed concepts pages; emphasises that score internals are not
  part of the public contract.

Cross-repo follow-ups for sherlock
- API still returns strategy_scores and judge_model_invoked on
  GET /api/v2/scans/{scan_id}. Remove from the response model so
  customers can't inspect detection internals via the field surface.
- Reason codes JUDGE_BUMP_UP, JUDGE_BUMP_DOWN, LLM_API_ERROR,
  LLM_PARSE_ERROR are emitted with internal terminology baked into
  the enum strings. Consider renaming (e.g. SCORE_ADJUSTED_UP,
  ANALYSIS_ERROR) so the public reason_codes list doesn't leak the
  same mechanics this PR scrubbed from prose.
The pipeline no longer carries completed_with_partial as a reserved
status — ScanStatusT is now just processing | completed | failed.
Scans that experience step failures land in `completed` with the
`coverage` object recording what was skipped. The partial_reason
webhook field went away with it.

Reason-code renames to match aggregator.py and llm_decision.py:
  CONTENT_SAFETY_TEXT_FLAGGED   -> TEXT_FLAGGED
  CONTENT_SAFETY_IMAGE_FLAGGED  -> IMAGE_FLAGGED
  CONTENT_FILTER_TRIGGERED      -> UNSAFE_CONTENT_BLOCKED
  JUDGE_BUMP_UP                 -> SECONDARY_REVIEW_CONFIRMED
  JUDGE_BUMP_DOWN               -> SECONDARY_REVIEW_DOWNGRADED
  LLM_API_ERROR                 -> ANALYSIS_ERROR
  LLM_PARSE_ERROR               -> PARSE_ERROR

Header note added that codes are an unordered set AND open-ended so
integrators code defensively against unknown codes.
Adds the recently-shipped public fields and surface changes from the
sherlock backend:

- Get scan: document `is_banned` (bool | null) at the top level of the
  scan record. Null until the ban-checker evaluates, then true/false.
- Create batch: tighten the partial-acceptance worked example so the
  ordering ("first N accepted, last `profiles_skipped` dropped") is
  unambiguous; use the 50-URL / 30-quota numbers from the worked
  example brief.
- Authentication + skill.md: dashboard-session-only list expands from
  three to five endpoints — POST /org/api-keys and GET /org/api-keys
  also reject API keys now (prevents API-key → API-key chaining).
- Errors: document the new 403 detail string for those two endpoints:
  "This endpoint requires a dashboard session. API keys are not
  permitted."
@maheshpchandran maheshpchandran merged commit 854e5fe into main May 20, 2026
1 check passed
@maheshpchandran maheshpchandran deleted the docs/sync-backend-changes branch May 20, 2026 08:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant