docs backend evidence community safety CS02B_HELPFULNESS_HTTP - AlexandreZanata/Abastevo GitHub Wiki
CS02B — Helpfulness HTTP and OpenAPI
Date: 2026-10-11. Status: LOCAL_DONE. Scope: HTTP routes, composition
wiring, OpenAPI schemas and contract vectors only — no migration/store
change (CS02A), no VPS/APK/dependency change. Head: maintained dev.
Plan: phased plan,
CS02A store. Rules: B-BR-CS02, BUC-CS02.
Routes (community/adapters/http, same proof/envelope conventions)
POST /v1/observations/{id}/helpfulness→ 201 with vote receipt, exact tally and owner overlay; auth required.POST /v1/observations/{id}/helpfulness/remove→ 200 with tally after tombstone; auth required.GET /v1/observations/{id}/helpfulness?decision_sequence=N→ 200 public counts;my_choiceonly on the authenticated read path, never public caches.- Bodies: 64 KiB cap, strict decode (unknown/duplicate/trailing rejected), UTF-8 enforced, canonical integer sequence ≥ 1, frozen choice checked at the wire and again in domain/application.
- Errors:
community.self-vote403,community.stale-revision409,community.invalid-vote400, plus the existing auth/blocked/ not-found/ineligible/bad-body codes. Responses carry no voter, account, key, device or cursor internals and areno-store. - Wiring:
cmd/api/main.gomounts realCast/Remove/TallyForoverHelpfulnessPorts(same account gate as votes).
Binding correction (found by the e2e test, fixed here)
Observations carry caller.Token as contributor reference, so the
application vote identity now binds caller.Token — exactly like
community confirmations — instead of the contributor ID; the account
gate keeps using the ID. Without this, self-votes would never refuse
(the e2e author-vote case returned 201 before the fix, 403 after).
CS01 unit fakes updated to per-caller tokens with contributor-scoped
submission keys. CS01 freeze wording is superseded accordingly:
one live vote per attribution+target+revision.
Validation (actual)
- Unit
adapters/http: 12 helpfulness tests green (happy paths, anonymous writes 401, 10 malformed bodies, UTF-8, 5 error mappings, remove zeroing + overlay cleared, anonymous tally without overlay or leaks, bad sequences, 404). - E2E
adapters/http(full-stack fixture with real signed proof and pg store): cast 201 + same-id crash replay, author self-vote 403, anonymous tally without overlay, stale 409, removal zeroes; tampered signature 401, unknown key 401, oversized 400, unknown target 404. Full package green (existing e2e unaffected). - CS02A store suite re-green after the token change (10/10,
concurrent trio under
-race). apicontract: 4 new vectors validate against the newHelpfulnessSubmit/Tallyschemas (spec self-check + local refs ok).go build ./...,go vet,gofmt -l,git diff --checkclean;scan-secrets.shpassed. Only disposable local test databases used.
Limits / owed
CONTRIBUTIONmoderation target + hide/delete writers: CS05.- Erasure footprint wiring (account → refs fan-out): CS09 path.
- Restricted DB roles: P08 provisioning.
- Android helpfulness cards/overlay: CS08/CS11 (strings.xml VALID/ INVALID collision already noted).
Next microtask: CS03 — admission and abuse protection.