Problem
Structured logs currently include raw student_id and attempted word values in messages and JSON fields. These logs can be shipped to third-party observability systems with retention and access rules that differ from the primary student store. They are also outside export_student_data, delete_student_data, and the documented retention sweep, so the promise to purge managed student data does not cover what the service emits.
Logging should support operations without creating a shadow store of children's activity.
Proposed change
- Define a data-classification and logging policy for identifiers, learning content, auth material, request bodies, and provider errors.
- Replace raw student identifiers with a keyed, environment-specific pseudonymous correlation value (or request-scoped ID); never use an unsalted public hash.
- Remove raw words and profile content from normal logs. Use bounded categorical fields and metrics instead.
- Add request/correlation IDs, latency, status, route template, provider outcome, and algorithm version so debugging remains useful.
- Add a redaction filter that covers structured extras, formatted messages, exception text, and authorization headers.
- Document external log retention/access obligations and clarify that application deletion cannot erase independently exported logs.
- Add automated capture tests that exercise success and failure paths and assert seeded secrets/student IDs/words never appear.
Acceptance criteria
- No raw student ID, guardian ID, API key, authorization header, word attempt, or story text is emitted by tested API/Bedrock/privacy paths.
- Operators can correlate a student's requests only through a protected, rotatable pseudonymization key or request IDs.
- JSON timestamps are valid UTC RFC 3339 values (including sub-second precision if claimed).
- Log schemas and retention guidance are documented.
- Regression tests fail on sensitive-field leakage in both plain-text and JSON logging modes.
Relevant code
agent/log_config.py
api/routes.py
agent/hint_generator.py
agent/story_mode.py
main.py
PRIVACY.md
Problem
Structured logs currently include raw
student_idand attemptedwordvalues in messages and JSON fields. These logs can be shipped to third-party observability systems with retention and access rules that differ from the primary student store. They are also outsideexport_student_data,delete_student_data, and the documented retention sweep, so the promise to purge managed student data does not cover what the service emits.Logging should support operations without creating a shadow store of children's activity.
Proposed change
Acceptance criteria
Relevant code
agent/log_config.pyapi/routes.pyagent/hint_generator.pyagent/story_mode.pymain.pyPRIVACY.md