Goal
R6 + R13 (staleness half of the unified heal) — every /query-intel call auto-checks its own staleness and self-heals inline (no separate refresh call), with a freshness threshold to avoid thrash, lock-aware, graceful-degrade. Reconcile to ONE staleness owner (retire the package-generator stamp duplication).
Implementation Sketch
scripts/intel-query.sh/intel_repo/neo4j/query_graph.pyread path: on each query, compute staleness viaintel_repo/neo4j/staleness.pyand compareSection.intel_package.generated_at_shaagainst the current graph head; on a stale-flag whose age exceeds the freshness-threshold TTL, trigger the existing lock-awarerefreshinline, then serve fresh data; refresh failure => serve stale + flag (never block the query).- Freshness-threshold TTL:
intel_repo/neo4j/staleness.pyis binary-stale today (stale | fresh, no age horizon). Add afreshness_ttlparameter (aDuration-typed staleness horizon) so inline auto-refresh fires ONLY when the stale window exceeds the TTL — without it every stale query thrashes a refresh. SCOPE inline auto-refresh to the LOW-LATENCY staleness classes (code,plan) only; HIGH-LATENCY classes (embedding,cpg) serve stale + flag and never trigger an inline refresh (their rebuild cost would block the query past any acceptable horizon — they refresh out-of-band). - Expose ONE heal entry — the unified heal wrapper
scripts/intel_package_runtime/heal.py:heal_section_package(plan_dir, section_id, *, freshness_ttl)— that the presence half (consumer-required-reading/s-9a707429) ALSO calls. Both halves invoke this single entry, comparingSection.intel_package.generated_at_shaagainst the graph head: the presence half routes themissing -> generatearm, the staleness half (this section) routes thestale-past-TTL -> refresharm. No second heal path (SSOT); the wrapper is the SOLE generate-or-refresh entry both halves share. Placement is ori_lang-side (scripts/intel_package_runtime/, the package runtime that ownsshould_regenerate+generate+persist), NOTintel_repo/neo4j/— the wrapper operates on planSection+ intel-package sidecars (ori_lang concepts) andintel_repomust not depend on ori_lang per its one-way data-flow boundary (intel_repo/CLAUDE.md). - Retire the package-generator
--priorstamp comparison once the query layer self-heals (one owner per R6).
Spec References
scripts/intel-query.sh(refreshsubcommand — already lock-aware, exits 0)intel_repo/neo4j/staleness.py(binary-stale staleness classifier — gains afreshness_ttlhorizon parameter + low-latency-vs-high-latency class scoping)scripts/intel_package_runtime/heal.py:heal_section_package(the SINGLE unified heal wrapper shared with the presence half; ori_lang-side per the intel_repo one-way boundary; comparesSection.intel_package.generated_at_shavs graph head via the existingshould_regeneratedecision)intel_repo/neo4j/staleness.pygraph-sidefreshness_ttlis the GRAPH self-heal horizon (distinct concern from the plan-section-package heal above; graph-older-than-HEAD inline refresh scoped to low-latency classes)scripts/intel_package_runtime/generate.py(the--priorstamp logic being retired)plans/intel-package-dossier-rebuild/content/consumer-required-reading--s-9a707429.md(presence half — calls the SAMEheal_section_packageentry)intel-package-rebuild-notes.mdR6, R13
Work Items
- Auto-refresh-on-stale read path: add a
freshness_ttl(Duration-typed staleness horizon) parameter tointel_repo/neo4j/staleness.py(today binary-stale, no age horizon); inline auto-refresh fires ONLY when the stale window exceeds the TTL, SCOPED to the low-latency staleness classes (code,plan); high-latency classes (embedding,cpg) serve stale + flag, never inline-refresh. Lock-aware (reuseintel-query.sh refresh) + graceful degrade (refresh failure => serve stale + flag, never block). - Single heal entry —
scripts/intel_package_runtime/heal.py:heal_section_package— shared with the presence half (consumer-required-reading/s-9a707429); this section routes thestale-past-TTL -> refresharm of the shared wrapper. No parallel heal path. - Retire the package-generator staleness stamp (one staleness owner).
Verification
FLAGGED FOR EXECUTION PHASE (plan.json edits — out of editor scope per the route-access ban at plan-read-discipline.md §2.1; same sanctioned pattern as schema-integration (s-e2117453) used for sc-0007):
- sc-0008 per-edge-case pins: success_criterion sc-0008 currently probes a generic suite bucket. During execution, tighten sc-0008 to NAMED per-edge-case pytest pins via the sanctioned write API (
scripts/plan_corpus/write.py:amend-success-criterion/ criterion edit), so the criterion’s probe asserts each edge case rather than a single bucket: (a) stale-past-TTL on a low-latency class (code/plan) triggers exactly ONE inline lock-aware refresh then serves fresh; (b) stale-within-TTL serves stale WITHOUT a refresh (no thrash); (c) a high-latency class (embedding/cpg) serves stale + flag and NEVER inline-refreshes; (d) refresh failure serves stale + flag and never blocks the query (graceful degrade); (e) the presence half and this staleness half both resolve through the SAMEheal_section_packageentry (SSOT — no second heal path). - work_items ordering dependency:
w-eee3706d(auto-refresh read path establishing thefreshness_ttlparameter + heal-arm wiring) MUST precedew-36680518(retire the package-generator stamp) — the stamp cannot be retired as the staleness owner until the query layer self-heals. Execution ORDER is ALREADY encoded by the lexorankkey(w-eee3706d<w-36680518); during execution, add the ADVISORY ordering edge ashint_needs:onw-36680518via the sanctioned work_item write API per.claude/rules/v7-plan-system.mdINV-6/INV-15.depends_onis a retired v7 field (WorkItem isadditionalProperties:false) — NEVER a raw plan.json edit, NEVER prose reordering.
HISTORY
- 2026-06-13 — heal-wrapper placement corrected (boundary-correct): the heal wrapper was specified at
intel_repo/neo4j/heal.py; execution-phase analysis found that placement inverts theintel_repoone-way data-flow boundary (intel_repo/CLAUDE.md: ori_lang has no dependency on / knowledge of the graph DB; data flows graph → ori_lang).heal_section_packageoperates on planSection+ intel-package sidecars (ori_lang concepts) and consumesshould_regenerate+generate+persist(allscripts/intel_package_runtime/), so it lands ori_lang-side atscripts/intel_package_runtime/heal.py. Two distinct staleness concerns are kept separate: GRAPH staleness (intel_repo/neo4j/staleness.pyfreshness_ttlgraph self-heal, low-latency classes inline) vs PLAN-SECTION-PACKAGE staleness (ori_langheal_section_packageviashould_regenerate). Each retains ONE owner (R6); the cross-boundary “single graph-side entry” reading is the corrected design.