This PR completes legal document tracking and enforcement for Terms of Service and Privacy Notice updates.
It upgrades the existing version-based legal tracking to exact-document tracking, ties each legal document row
to immutable caution/website source metadata, adds a production-ready web acceptance flow, and enforces
blocking re-acceptance at the API layer. It also adds minimum viable CLI handling so blocked CLI users get a
clear message instead of a generic API failure.
What’s Included
- Added legal document provenance fields to legal_documents:
- source_commit_sha
- source_path
- content_sha256
- Added legal_document_id to user_legal_events so each acceptance event points to an exact legal artifact row
- Backfilled current seeded ToS and Privacy Notice rows with source metadata from caution/website
- Updated signup and legal re-acceptance flows to record the exact legal_documents row accepted
- Updated legal status computation to compare exact document identity, not just display version strings
- Added backend legal enforcement middleware for active documents marked requires_blocking_reacceptance = true
- Kept /api/user/status and /api/legal/accept reachable while users are blocked
- Added frontend legal acceptance modal with:
- single-document and both-document flows
- accept and decline/log-out path
- app-shell integration so blocked users cannot continue using the platform
- Added a small Settings > Legal read-only section showing acceptance history and document links
- Added minimum viable CLI handling for legal_acceptance_required so CLI users see a targeted recovery message
- Added an operator helper script to create new inactive legal-document rows from a caution/website repo path
- Updated admin tooling and legal e2e tests for the new provenance/document-id model
Behavioral Outcome
- New users still get legal acceptance recorded at signup
- Existing users with outdated active legal documents are prompted to review and accept updates in the web app
- If an active document requires blocking re-acceptance, protected API access is denied until acceptance is
recorded
- CLI users are also blocked by the same backend rule, but now receive a clear message directing them to the
web app
Testing
Verified:
- frontend build
- API legal unit tests
- CLI tests
- legal e2e flow
- manual web testing for:
- Terms only outdated
- Privacy only outdated
- both outdated
- accept path
- decline/back path
- logout/re-login persistence
- dashboard recovery after acceptance
- manual CLI blocked-path check for apps list
Future Work
- Add a first-class CLI legal review/accept flow instead of only redirecting users to the web app
- Optionally expand Settings > Legal into a fuller legal-history view if we want more user-facing audit
visibility
This PR completes legal document tracking and enforcement for Terms of Service and Privacy Notice updates.
It upgrades the existing version-based legal tracking to exact-document tracking, ties each legal document row
to immutable caution/website source metadata, adds a production-ready web acceptance flow, and enforces
blocking re-acceptance at the API layer. It also adds minimum viable CLI handling so blocked CLI users get a
clear message instead of a generic API failure.
### What’s Included
- Added legal document provenance fields to legal_documents:
- source_commit_sha
- source_path
- content_sha256
- Added legal_document_id to user_legal_events so each acceptance event points to an exact legal artifact row
- Backfilled current seeded ToS and Privacy Notice rows with source metadata from caution/website
- Updated signup and legal re-acceptance flows to record the exact legal_documents row accepted
- Updated legal status computation to compare exact document identity, not just display version strings
- Added backend legal enforcement middleware for active documents marked requires_blocking_reacceptance = true
- Kept /api/user/status and /api/legal/accept reachable while users are blocked
- Added frontend legal acceptance modal with:
- single-document and both-document flows
- accept and decline/log-out path
- app-shell integration so blocked users cannot continue using the platform
- Added a small Settings > Legal read-only section showing acceptance history and document links
- Added minimum viable CLI handling for legal_acceptance_required so CLI users see a targeted recovery message
- Added an operator helper script to create new inactive legal-document rows from a caution/website repo path
+ commit
- Updated admin tooling and legal e2e tests for the new provenance/document-id model
### Behavioral Outcome
- New users still get legal acceptance recorded at signup
- Existing users with outdated active legal documents are prompted to review and accept updates in the web app
- If an active document requires blocking re-acceptance, protected API access is denied until acceptance is
recorded
- CLI users are also blocked by the same backend rule, but now receive a clear message directing them to the
web app
## Testing
### Verified:
- frontend build
- API legal unit tests
- CLI tests
- legal e2e flow
- manual web testing for:
- Terms only outdated
- Privacy only outdated
- both outdated
- accept path
- decline/back path
- logout/re-login persistence
- dashboard recovery after acceptance
- manual CLI blocked-path check for apps list
## Future Work
- Add a first-class CLI legal review/accept flow instead of only redirecting users to the web app
- Optionally expand Settings > Legal into a fuller legal-history view if we want more user-facing audit
visibility