{"record":{"id":"adeb58e1a45e04e8","repo":"HKUDS/DeepTutor","slug":"preferences-md-is-not-audited-automatically","errorCode":null,"errorMessage":"preferences.md is not audited automatically","messagePattern":"preferences\\.md is not audited automatically","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"deeptutor/services/memory/consolidator/modes/audit.py","lineNumber":278,"sourceCode":"        edits_rejected=edits_rejected,\n    )\n\n\n# ── L3 ──────────────────────────────────────────────────────────────────\n\n\nasync def _run_audit_l3(\n    slot: L3Slot,\n    *,\n    language: str,\n    user_label: str,\n    budget: int,\n    llm_selection: dict | None,\n    on_event: OnEvent | None,\n    settings,\n) -> AuditResult:\n    if slot == \"preferences\":\n        raise ValueError(\"preferences.md is not audited automatically\")\n\n    l3_path = paths.l3_file(slot)\n    if not l3_path.exists():\n        await emit(on_event, {\"stage\": \"done\", \"no_doc\": True})\n        return AuditResult(layer=\"L3\", key=slot, chunks_processed=0, no_doc=True)\n\n    doc = load_doc(l3_path, default_title=f\"{slot} memory\")\n    l2_lookup = _build_l2_entry_lookup()\n    prompt = load_prompt(\"audit_l3\", language)\n    focus, _sections = slot_focus(language, slot)\n\n    annotated_text, _ranges = _build_annotated_l3(doc, l2_lookup)\n    chunks = chunk_with_boundary(\n        annotated_text,\n        budget=budget,\n        overlap_ratio=settings.chunking.overlap_ratio,\n        min_chunk_chars=settings.chunking.min_chunk_chars,\n        max_chunk_chars=settings.chunking.max_chunk_chars,","sourceCodeStart":260,"sourceCodeEnd":296,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/services/memory/consolidator/modes/audit.py#L260-L296","documentation":"The audit mode mirrors the consolidator: the preferences.md L3 document is maintained by hand and is never auto-audited. _run_audit_l3 raises immediately when slot == 'preferences', before touching the file.","triggerScenarios":"Calling run_audit(layer=\"L3\", key=\"preferences\") (directly or through a batch driver like go()) — the guard fires before the l3_file existence check.","commonSituations":"Running an audit sweep over every L3 slot and forgetting to exclude preferences; porting a consolidation loop to the audit API without carrying over the same exclusion.","solutions":["Exclude 'preferences' from L3 audit sweeps","Audit preferences.md manually (read and edit the file) if review is needed","Centralize the exclusion in a helper like is_auto_managed(slot) so consolidator and audit stay in sync"],"exampleFix":"# before\nfor slot in l3_slots:\n    await run_audit(\"L3\", slot, ...)\n# after\nfor slot in l3_slots:\n    if slot != \"preferences\":\n        await run_audit(\"L3\", slot, ...)","handlingStrategy":"validation","validationCode":"if slot == \"preferences\":\n    skip(\"preferences.md is maintained manually\")\nelse:\n    await run_audit(\"L3\", slot, ...)","typeGuard":"def is_auditable(slot: str) -> bool:\n    return slot != \"preferences\"","tryCatchPattern":"try:\n    await run_audit(\"L3\", slot)\nexcept ValueError as e:\n    if \"not audited automatically\" in str(e):\n        continue\n    raise","preventionTips":["Reuse the same preferences exclusion across consolidate and audit sweeps"],"tags":["memory","audit","guard-clause","deepseek-tutor"],"backgroundTag":"excluded-slot-guard","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}