HKUDS/DeepTutor · error · ValueError

preferences.md is not audited automatically

Error message

preferences.md is not audited automatically

What it means

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.

Solutions

  1. Exclude 'preferences' from L3 audit sweeps
  2. Audit preferences.md manually (read and edit the file) if review is needed
  3. Centralize the exclusion in a helper like is_auto_managed(slot) so consolidator and audit stay in sync

Example fix

# before
for slot in l3_slots:
    await run_audit("L3", slot, ...)
# after
for slot in l3_slots:
    if slot != "preferences":
        await run_audit("L3", slot, ...)
Defensive patterns

Strategy: validation

Validate before calling

if slot == "preferences":
    skip("preferences.md is maintained manually")
else:
    await run_audit("L3", slot, ...)

Type guard

def is_auditable(slot: str) -> bool:
    return slot != "preferences"

Try / catch

try:
    await run_audit("L3", slot)
except ValueError as e:
    if "not audited automatically" in str(e):
        continue
    raise

Prevention

When it happens

Trigger: Calling run_audit(layer="L3", key="preferences") (directly or through a batch driver like go()) — the guard fires before the l3_file existence check.

Common situations: 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.

Related errors


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/adeb58e1a45e04e8. Report an issue: GitHub.

Appendix: source

Thrown at deeptutor/services/memory/consolidator/modes/audit.py:278

        edits_rejected=edits_rejected,
    )


# ── L3 ──────────────────────────────────────────────────────────────────


async def _run_audit_l3(
    slot: L3Slot,
    *,
    language: str,
    user_label: str,
    budget: int,
    llm_selection: dict | None,
    on_event: OnEvent | None,
    settings,
) -> AuditResult:
    if slot == "preferences":
        raise ValueError("preferences.md is not audited automatically")

    l3_path = paths.l3_file(slot)
    if not l3_path.exists():
        await emit(on_event, {"stage": "done", "no_doc": True})
        return AuditResult(layer="L3", key=slot, chunks_processed=0, no_doc=True)

    doc = load_doc(l3_path, default_title=f"{slot} memory")
    l2_lookup = _build_l2_entry_lookup()
    prompt = load_prompt("audit_l3", language)
    focus, _sections = slot_focus(language, slot)

    annotated_text, _ranges = _build_annotated_l3(doc, l2_lookup)
    chunks = chunk_with_boundary(
        annotated_text,
        budget=budget,
        overlap_ratio=settings.chunking.overlap_ratio,
        min_chunk_chars=settings.chunking.min_chunk_chars,
        max_chunk_chars=settings.chunking.max_chunk_chars,

View on GitHub (pinned to 3e82f13042)