Arcqtype

Community

Community Standards

Effective: Pending attorney review · Last updated July 29, 2026 (draft) · counsel-review draft

Draft — pending attorney review. This document reflects how Arcqtype is built today but has not yet received final legal sign-off. Wording may change before launch.

0. Purpose & scope

Arcqtype is a youth-athlete training and recruiting platform for student-athletes age 13 and older under the launch posture. Many users are minors. This policy governs user-generated content (UGC) and community interaction on Arcqtype: what athletes may contribute, what is prohibited, how content is moderated, and how minors are protected from contact and exposure.

This policy is intended to satisfy the App Store Review Guideline 1.2 requirement that apps with user-generated content provide (a) a method to filter objectionable content, (b) a mechanism to report offensive content and timely action, (c) the ability to block abusive users, and (d) published contact information. It pairs with the Terms of Service and the COPPA/Minors compliance doc.

2026-07-09 privacy promise: final publication should align with the locked statement "we never sell personal data". Moderation reports, blocks, mutes, safety signals, and community content must not be used for advertising, data brokerage, or sale/share-for-value.

What counts as UGC on Arcqtype today

Grounded in the moderation route's accepted content_type enum and the iOS report sheet, the reportable/moderated UGC surfaces are:

  • Surface — What the user contributes — Where it appears — Code anchor
  • Profile — Athlete profile (name surfaced as display name, sport, position, state, bio) — Leaderboards, crew/challenge rosters, recruiting visibility — content_type: 'profile'
  • Leaderboard entry — The athlete's ranked row (display name + ARQ score + metrics) — Public ARQ leaderboard, sport/state/age-filtered boards — content_type: 'leaderboard_post'
  • Challenge — Challenge title + description (free text) — Public challenge discovery feed — content_type: 'challenge'; challenges.routes.ts:309-331
  • Challenge entry — Participation in a challenge — Per-challenge leaderboard — content_type: 'challenge_entry'
  • Crew — Crew name + description (free text) — Visible to invited members (and any future cross-crew discovery) — content_type: 'crew'; crews.routes.ts:92-114
  • Crew activity — Activity-feed posts within a crew — Crew activity feed (members only) — content_type: 'crew_activity'
  • Document — Uploaded athlete documents — Athlete's own document workspace — content_type: 'document'

Note on Coach chat (the AI persona). Messages an athlete sends to Coach are *not* peer-to-peer UGC — they are 1:1 inputs to OpenAI GPT-5-mini through Arcqtype's OpenAI-only provider seam. They are governed separately by the AI/safety pre-filter described in §6 and by the AI-disclosure and privacy docs. Coach chat is not posted to or visible to other users. This policy covers it only insofar as the same safety classifier gates both Coach chat and public-UGC writes.

---

1. Who this applies to

  • All Arcqtype users who view or contribute community content.
  • Minor users (under 18) and under-13 users receive the additional protections in §7. The platform enforces a COPPA hard gate server-side: under-13 (and unknown-DOB) users cannot save profile PII without a verified, unexpired, non-revoked guardian-consent token, and every successful minor PII save writes a coppa_audit_log row.

---

2. Acceptable use

When contributing community content (profile fields, challenge/crew text, activity posts, leaderboard participation), athletes agree to:

  • Keep content focused on training, performance, recovery, nutrition, and recruiting — the purpose of the platform.
  • Contribute truthful performance data and profile information. (Performance metrics may carry a verification status; see verification_status in community.routes.ts.)
  • Respect other athletes, including competitors, teammates, and athletes on other teams.
  • Respect the privacy of others — do not post another person's personal contact information, location, or images without permission.
  • Use the reporting and blocking tools (§4) rather than retaliating.

---

3. Prohibited content & conduct

The following are not allowed in any community surface. Categories below are grounded in the report-reason enum the app actually offers and the automated safety-classifier categories.

3.1 Report reasons offered to users

The in-app report sheet lets a user file a report under one of these reasons:

  • Harassment or bullying
  • Inappropriate content
  • Spam
  • Safety concern
  • Copyright
  • Something else

3.2 Categories the automated classifier blocks

The shared safety classifier flags the following category families. It gates both Coach chat input/output and pre-publish public-UGC text (challenge/crew names + descriptions) via moderatePublicText:

  • Self-harm / suicidal content — first-person phrasing flags unconditionally; second-person ("kill yourself") flags when not protectively negated.
  • Unsafe weight cutting / disordered eating — e.g., dehydration cuts, sauna suits, laxatives/diuretics for weigh-ins, starvation.
  • Violence — weapon/attack/serious-harm phrasing, with a sports-context override so competitive language ("crush them," "destroy the opponent") is not falsely flagged.
  • Sexual content involving minors.
  • Illicit drugs and PED/steroid misuse.
  • Medical red flags — symptoms paired with intent to keep playing/training.
  • Abusive adult-toward-minor language.
  • Privacy / internal-disclosure and prompt-injection attempts.

3.3 Additional prohibited conduct (policy-level; not all automatically detected today)

The following should be prohibited by policy even where the current classifier does not detect them automatically (counsel to confirm enforceability; product to confirm detection roadmap):

  • Posting another user's personal contact information (phone, email, home address, social handles) — especially a minor's.
  • Impersonation of another athlete, coach, recruiter, or organization.
  • Solicitation of off-platform contact with a minor by an adult.
  • Commercial spam, scams, or unauthorized recruiting/agent solicitation.
  • Intellectual-property infringement (the copyright report reason exists for user reports).

---

4. Reporting, blocking, and muting

All three tools are implemented end-to-end (iOS UI → backend route → durable storage). They are surfaced from a context menu on each non-self row on the Leaderboard, with the same pattern intended for Crews and Challenges. Self-rows skip the menu — a user cannot moderate themselves.

4.1 Report content

  • User flow: the ReportContentSheet lets the reporter pick a reason and add optional free-text details (max 2000 chars), then submits.
  • Backend: POST /api/moderation/report inserts a row into moderation_reports with reporter_user_id, content_type, content_id, reason, details, and status: 'pending'. Every filed report is logged.
  • Validation: content_type must be one of the seven allowed types; content_id must be a UUID; reason must be one of the six allowed reasons.

4.2 Block a user

  • Backend: POST /api/moderation/blocks upserts into user_blocks (blocker → blocked); DELETE /api/moderation/blocks/:userId removes it; GET /api/moderation/blocks lists the caller's blocks. Self-block is rejected.
  • Effect on reads: blocked users' rows are hidden from the public ARQ leaderboard, the per-challenge leaderboard, and any surface that calls getViewerHiddenUserIds / getBlockedUserIds. iOS caches the block list in memory and refreshes on launch and after each mutation.

4.3 Mute a user

  • Backend: POST /api/moderation/mutes / DELETE /api/moderation/mutes/:userId / GET /api/moderation/mutes on the user_mutes table. Self-mute is rejected.
  • Effect on reads: mute is described in code as a *softer hide* — surfaces may render but de-emphasize — but today most surfaces filter mutes the same as blocks. *Open question for counsel/product: confirm whether mute and block should remain functionally identical for the public-board use case, or whether mute should be a true soft-hide.*

4.4 Reporter feedback

  • On success the report sheet simply dismisses; on failure it shows "Could not submit report. Please try again.". There is no in-app status/outcome notification back to the reporter today — *open question: App Store 1.2 and several jurisdictions favor telling the reporter that action was taken; decide on a reporter-feedback mechanism.*

---

5. Moderation operations & action

5.1 Triage queue

Filed reports land in moderation_reports with status: 'pending'. *Open question for counsel/ops: there is no documented SLA or staffed review process in code — App Store 1.2 expects "act on objectionable content reports within 24 hours." Define and document the response-time commitment and who performs review.*

5.2 Takedown

  • Backend: POST /api/moderation/takedowns performs a soft takedown — it sets taken_down_at, taken_down_by, and takedown_reason on the target row (profile / challenge / challenge entry / crew / crew activity / leaderboard snapshot) and marks matching pending reports as actioned with a resolved_at timestamp.
  • Auth gap (material — flag for counsel + product): there is no admin role in the codebase yet. The takedown route is gated only by an environment-variable shared secret passed as X-Admin-Token. taken_down_by is written as null because there is no admin user id. The route returns 503 admin_takedown_unavailable if the secret is unset. *This must be replaced with a real, auditable admin/moderator role before this can be represented to users or regulators as a staffed moderation capability.*

5.3 Enforcement ladder (policy-level — confirm with counsel)

Proposed, not yet codified beyond the takedown primitive: 1. Automated pre-publish block of flagged text (already enforced; §6). 2. Soft takedown of reported content. 3. Warning / temporary restriction of a repeat offender. 4. Account suspension or termination for severe or repeated violations (especially anything in §3.2 involving minors). *Open question: define the escalation thresholds and the appeal path.*

---

6. Automated content safety (pre-publish + AI)

Arcqtype runs a fail-safe-closed safety classifier as a content gate.

  • Posture: by default, if the classifier errors or times out, content is blocked, not allowed. An emergency bypass exists but is logged loudly and is intended only for the rare case where the classifier itself is the production incident. This is the correct posture for a youth product.
  • Pre-publish UGC gate: challenge and crew creation run the title + description through moderatePublicText before insert; flagged content returns 403 { error: 'CONTENT_FLAGGED' } and is never stored.
  • Coach (AI) chat: the same classifier gates Coach input and Coach output. Flagged self-harm content triggers a crisis-resource redirect (Crisis Text Line — text HOME to 741741) rather than a generic refusal. Suggested follow-up chips on a flagged turn are re-validated individually or suppressed.
  • AI training disclosure (engineering fact, counsel wording pending): Arcqtype has no training or fine-tuning pipeline and sends Coach messages to OpenAI GPT-5-mini to generate a response. Any provider-side no-training or retention representation must match the executed OpenAI agreement and live settings. This is covered in detail by ai-disclosure-and-no-training-statement.md and third-party-subprocessors.md; it is restated here because Coach chat is the largest free-text input surface.

Detection limits (be candid with counsel): the public-UGC classifier today is a regex/keyword-based heuristic, not an ML moderation model. It will miss obfuscated abuse, novel slang, image content, and most PII patterns. Do not represent moderation as comprehensive. The sports-context override is deliberately permissive to avoid false positives on competitive language, which means some borderline-violent phrasing passes.

---

7. Minor safety (under-18 and under-13)

This is the highest-risk area. The following are grounded in code.

7.1 No public PII by default — identity anonymization on leaderboards

  • On the public ARQ leaderboard and per-challenge leaderboards, a user with no privacy-settings row defaults to anonymized — their name is replaced with an opaque label Athlete #NNNN. The signed-in user always sees their own real row (self-exception).
  • Users who are opted out or private are fully hidden from public boards.
  • Default privacy settings are { visibility: 'sport_only', opted_in: true, anonymized: true } — i.e., a new athlete appears on the board anonymized by name unless they affirmatively un-anonymize.
  • Display-name shape: the leaderboard recalculation writes display_name as first name + last initial (e.g., "Marcus J."), which is itself a PII-minimizing choice. *Open question / discrepancy to resolve: the privacy read-paths in leaderboard.service.ts:207-209 build a fuller ${first_name} ${last_name} for un-anonymized rows, while the stored display_name (and the route iOS calls) uses first-name + last-initial. Counsel + engineering should confirm exactly what surfaces a minor's full last name, and standardize on the minimal form for minors.*

7.2 Contact safety — no open contact channels between users

  • There is no peer-to-peer direct-messaging surface between athletes in the community feature set reviewed. Crews are invite-code-gated with a membership check on every read, and crew/challenge content is moderated pre-publish. This materially reduces stranger-contact risk for minors.
  • *Open question for counsel: the recruiting/Network surfaces are adjacent contact channels not covered by this UGC policy — confirm whether athlete↔college-coach outreach needs its own contact-safety policy, and whether any of those channels are reachable by under-13 users.*

7.3 Guardian consent & audit (COPPA)

  • Under-13 / unknown-DOB users cannot save profile PII without a verified guardian-consent token, and minor PII writes are audited. This means a child's profile data — the input to any community surface — cannot exist without guardian consent in the first place. Full treatment lives in coppa-minors-compliance.md.

7.4 Minor-specific moderation posture

  • The safety classifier explicitly flags sexual content involving minors and abusive adult-toward-minor language as their own categories, and is fail-safe-closed.
  • *Open question: define whether reports involving a minor and any §3.2 category trigger an expedited / prioritized review path and any mandatory-reporting workflow (e.g., NCMEC referral for CSAM). This is a legal/ops decision, not currently in code.*

---

8. Data retention for moderation records

  • moderation_reports, user_blocks, and user_mutes rows persist in Supabase. Soft-takedown fields persist on the content rows. *Open question: define retention periods for moderation records (reports, takedown logs, COPPA audit rows) consistent with the privacy policy and any legal-hold obligations.* Cross-reference account-deletion-data-retention.md (status: needed).

---

9. Contact / abuse reporting (App Store 1.2 published-contact requirement)

  • *Placeholder — counsel/product to supply:* a published abuse-report contact (e.g., safety@arcqtype.com or equivalent), and the legal entity name + address that should appear in-app and in the App Store listing. The in-app reporting tools (§4) satisfy the in-product reporting requirement, but a published external contact is also expected.

---

10. Changes to this policy

Per the legal-lane process, any product change that adds a new UGC/social surface, a new contact channel, a new minor-facing flow, or alters the moderation pipeline must update this doc in the same unit of work. Material changes should be re-reviewed by counsel.

---

Appendix B — Primary code anchors (verify before relying)

  • arcqtype-api/src/routes/moderation.routes.ts — report / block / mute / takedown routes + enums
  • arcqtype-api/src/services/ugc-moderation.service.ts — viewer-hidden sets + pre-publish gate
  • arcqtype-api/src/services/moderation.service.ts — safety classifier, categories, fail-safe-closed posture, crisis copy
  • arcqtype-api/src/routes/community.routes.ts — public leaderboard read + privacy/block/mute enforcement
  • arcqtype-api/src/routes/challenges.routes.ts, crews.routes.ts — public UGC writes + pre-publish moderation
  • arcqtype-api/src/services/leaderboard-privacy.service.ts + leaderboard.service.ts — anonymization / hide policy + defaults
  • arcqtype-api/src/services/recalculation/leaderboard-updater.ts — stored display_name shape (first + last initial)
  • arcqtype-api/src/middleware/coppa.ts — under-13 guardian-consent gate + audit
  • arcqtype-api/src/services/chat/coach-chat.service.ts — Coach input/output moderation wiring
  • Arcqtype/Arcqtype/Core/Services/ModerationService.swift, Core/Views/ReportContentSheet.swift, Features/Community/LeaderboardView.swift — iOS report/block/mute UI
PrivacyTermsHealth dataDeletionSubprocessorsCommunityLicensesSupport© 2026 Arcqtype, Inc.