Goal
Target-kind-aware tier selection (R3): the active_tiers set per target kind — bug, plan-section, symbol-set, diff, subsystem. A tier renders only when its key is in the kind’s active set, and only active-tier selectors execute their graph queries.
Implementation Sketch
scripts/intel_package_runtime/tier_selection.py: derives the active tier set per target kind by INVERTING the tier registry’sowning_target_kindsfield (thetiers.pyregistry is the SSOT pergenre-inversion-tierss-1fe9a664 —active_tiers(kind) = [t for t in REGISTRY if kind in t["owning_target_kinds"]]). It carries NO hard-coded kind->tier-list vocabulary; the tier vocabulary lives in exactly one place (the registry’s 15 entries). Because the derivation is a pure inversion ofowning_target_kinds, the body names NO tier key outside the registry SSOT — the authoritative per-kind mapping is asserted by theactive_tiersverification test (tests section s-15e599fa), not duplicated as source data here.- The
TARGET_KINDSreconcile is ALREADY DONE in code (work itemw-bca82065reconcile sub-unit below). The single SSOT isscripts/intel_package_runtime/target_kinds.py(the closed frozenset{plan-section, bug, diff, symbol-set, subsystem}, lifted to its own module to break theenvelope -> tiersimport cycle).envelope.py:24re-exports it (from .target_kinds import TARGET_KINDS; theenvelope.py:26name is now a re-export, NOT a divergent declaration) andtiers.py:25imports it the same way (from .target_kinds import TARGET_KINDS). No divergent re-declaration remains intiers.py.subsystemis already present in the SSOT. Remaining w-bca82065 work is the per-kind active-tier THREADING, not the taxonomy reconcile. - The
subsystemtarget kind is ALREADY present across every SSOT sync point (target_kinds.py,envelope.pySURFACE_MATRIX + build_surfaces,target_resolve.pyis_resolvable,generate.pydynamic taxonomy) — verify-only at implementation (work itemw-bca82065sub-unit below). - Thread the per-kind active-tier set through
envelope.py:build_dossier->tiers.py:assemble_tiers(work itemw-bca82065sub-unit below) so inactive-tier selectors are skipped before query execution. - The per-kind narrowing happens at the CALL SITE
render.py:164(active = active_tiers_from(tiers.keys())): change its argument from the FULLtiers.keys()set to the per-kindactive_tiers(kind)list so only active-tier guards render true. Theactive_tiers_fromFUNCTION (render.py:66) is reused unchanged — it maps names throughguard_keyand drops the meta-tier.
Per-kind active-tier matrix (derived, not authored)
The matrix below is the OUTPUT of active_tiers(kind) = [t for t in REGISTRY if kind in t["owning_target_kinds"]] over the reconciled TARGET_KINDS.
-
Reproduced here as a derivation check ONLY — the
tiers.py:REGISTRYowning_target_kindsfields remain the SSOT and the s-15e599fa test is the authoritative assertion. -
Counts include the always-present
coverage-gapsmeta-tier (_ALL_KINDS). -
bug— every tier whoseowning_target_kindscontainsbug:terrain,dependency-graph,semantic-neighbors,hidden-callers,surprises,co-change,community-span,test-posture,churn,bug-cluster,plan-ownership,prior-art,sentiment,coverage-gaps(14 of 15 registry tiers;missing-abstractionis the only excluded registry tier), PLUS the bug-onlydefectVIRTUAL tier (15 guard keys total forbug).defectis NOT atiers.py:REGISTRYentry and is NOT emitted by the registry inversion orrender.py:_REGISTRY_TO_GUARD(line 36-54, which carries nodefectkey); the template guard{% if 'defect' in active_tiers %}(package.md.j2:41) gates the bug-only## 1. The defectsection (intel-package-example.md:31) ondefectmembership. The active-tier selector therefore INJECTSdefectinto the bug active set as a virtual (non-registry) guard key AFTER the registry inversion — see the virtual-tier injection inw-605bd83b.defectlights ONLY forbug; no other kind receives it. The s-15e599fa per-kind test asserts'defect' in active_tiers(bug)AND'defect' not in active_tiers(kind)for every non-bug kind. -
plan-section—terrain,dependency-graph,test-posture,plan-ownership,coverage-gaps(5). -
symbol-set—terrain,dependency-graph,semantic-neighbors,hidden-callers,missing-abstraction,prior-art,coverage-gaps(7). -
subsystem— all 15 tiers (subsystemis in everyowning_target_kindsentry, the broad-context kind). -
diff—diffis already a member oftiers.py:350_ALL_KINDS(the tuple is("bug", "plan-section", "symbol-set", "subsystem", "diff"), carrying the comment “per target-kind-tiers s-aa802633”). Every tier whoseowning_target_kindsis_ALL_KINDStherefore already lights for a diff target:terrain(tiers.py:360),dependency-graph(tiers.py:368), and the always-presentcoverage-gapsmeta-tier (tiers.py:472) — a non-empty diff active set today. The s-15e599fa testtest_active_tiers_diff_set_is_the_definitive_fiveasserts this exact 5-tier diff active set. The DEFINITIVE remaining diff-extension set (adddiffto each tier’sowning_target_kindstuple, in this order) is exactly two analytic tiers:semantic-neighbors(tiers.py:376, today("bug", "symbol-set", "subsystem")) andhidden-callers(tiers.py:384, today("bug", "symbol-set", "subsystem")). Both are symbol-graph-adjacency tiers that operate on the diff’s resolved changed-file symbol set (per thediff:<ref>resolver) and therefore carry real signal for a code-change target. No other analytic tier is extended fordiff:surprises/co-change/community-span/churn/sentiment/bug-clusterare bug/subsystem-scoped diagnostics,test-posture/plan-ownershipare plan/bug-scoped,missing-abstractionis symbol-set/subsystem-scoped — none is meaningful for a raw diff target. The resulting diff active set is thereforeterrain,dependency-graph,semantic-neighbors,hidden-callers,coverage-gaps(5). The s-15e599fa per-kind test coversdiffalongside the other four reconciled kinds and asserts this exact 5-tier set so no kind in the SSOT lacks a per-kind tier set + assertion.
Spec References
scripts/intel_package_runtime/target_kinds.py—TARGET_KINDSfrozenset (the closed taxonomy SSOT; all five kinds incl.subsystem).scripts/intel_package_runtime/tiers.py—REGISTRY(lines 355-476)owning_target_kindsper entry;TARGET_KINDSre-import (line 25,from .target_kinds import TARGET_KINDS);_ALL_KINDS(line 350);ANALYTIC_TIERS(line 480);assemble_tiers(line 484);semantic-neighborsentry (line 376) +hidden-callersentry (line 384) — the two diff-extension targets.scripts/intel_package_runtime/envelope.py—TARGET_KINDSre-export (line 24,from .target_kinds import TARGET_KINDS);SURFACE_MATRIX(line 44,subsystementry present);build_surfaces(line 115,subsystembranch at line 151);build_dossier.scripts/intel_package_runtime/target_resolve.py—is_valid_kind(line 30);is_resolvable(line 32,subsystembranch at line 45); importsTARGET_KINDSfromenvelope(line 13).scripts/intel_package_runtime/generate.py— invalid-kind error message (line 143, derives taxonomy fromsorted(TARGET_KINDS)dynamically).scripts/intel_package_runtime/render.py—active_tiers_fromFUNCTION (line 66, unchanged); its CALL SITE (line 164,active = active_tiers_from(tiers.keys())) is the per-kind narrowing point;defectNone-bind block (lines 387-394, the defect-population target).scripts/plan_corpus/schemas.py:1845BUG_SUBSYSTEM_TO_CRATES— the canonical subsystem-name vocabulary the subsystem ref grammar draws from.intel-package-template.md.j2(the{% if 'tier' in active_tiers %}guards);intel-package-rebuild-notes.mdR3.
Work Items
-
tier_selection.py— deriveactive_tiers(kind)purely by invertingtiers.py:REGISTRYowning_target_kinds; carry no hard-coded kind->tier vocabulary. AFTER the registry inversion, inject the bug-onlydefectVIRTUAL guard key:active_tiers(kind)appends"defect"to the result iffkind == "bug".defectis the ONLY virtual (non-registry) guard key; it is named once intier_selection.pyas the bug-only injection constant (not atiers.py:REGISTRYentry, never round-tripped throughrender.py:_REGISTRY_TO_GUARD). This is what makes{% if 'defect' in active_tiers %}(package.md.j2:41) fire for bug targets and stay false for every other kind.envelope.py:build_dossierconsumes the per-kind set. The implementer changes the CALLER atrender.py:164— todayactive = active_tiers_from(tiers.keys())(the full registry-tier set) — to feed the per-kindactive_tiers(kind)list instead:active = active_tiers_from(active_tiers(kind))(or equivalent: pass the narrowed name list into the existingactive_tiers_from). Theactive_tiers_fromFUNCTION atrender.py:66is NOT modified — it already drops thecoverage-gapsmeta-tier and identity-maps non-_REGISTRY_TO_GUARDkeys, so the injecteddefectpasses through unchanged; only its CALL SITE (line 164) changes which name set it receives. Implementation notes for the call-site change:render.pytoday imports neithertier_selectionnoractive_tiers(verified — render.py imports onlyre,Path,Any, jinja2, andverdicts), so the implementer addsfrom .tier_selection import active_tiersto render.py;kindis already bound at render.py:154 (kind = _str(target.get("kind"))), so the per-kind callactive_tiers(kind)at render.py:164 has itskindargument in scope without further plumbing. - Add the
subsystemtarget kind AND reconcile the taxonomy SSOT AND thread the per-kind active-tier set — three sub-units of one cohesive taxonomy-extension deliverable:- Reconcile
TARGET_KINDSto ONE SSOT — ALREADY DONE. The SSOT isscripts/intel_package_runtime/target_kinds.py(the closed frozenset, lifted to its own module to break theenvelope -> tiersimport cycle).envelope.py:24re-exports it;tiers.py:25imports it; no divergent re-declaration remains.subsystemis in the SSOT.diffSTAYS a kind — it has aSURFACE_MATRIXentry (envelope.py:44) + abuild_surfacesbranch + anis_resolvablebranch (target_resolve.py). No remaining reconcile work; the s-15e599fa per-kind tests cover all five kinds. - Thread the per-kind active-tier set from
envelope.py:build_dossierintotiers.py:assemble_tiers(line 484) soassemble_tierswalks only the active-tier subset ofANALYTIC_TIERS(line 480) and skips every inactive-tier selector BEFORE running its query — no wasted graph calls. This threading is the genuine REMAINING w-bca82065 work. For the diff active set, extend exactly two analytic tiers’owning_target_kindsto includediff:semantic-neighbors(tiers.py:376) andhidden-callers(tiers.py:384) — the definitive diff-extension set per the matrixdiffrow above (terrain/dependency-graph/coverage-gapsalready carrydiffvia_ALL_KINDSattiers.py:350). The s-15e599fa tests own a NEGATIVE assertion proving an inactive-tier selector is never invoked for a given kind. subsystemkind across EVERY SSOT sync point — ALREADY DONE (verify-only at implementation; do NOT re-add):target_kinds.pyTARGET_KINDS—subsystempresent in the frozenset.envelope.pySURFACE_MATRIX(line 44) —subsystementry present (("bugs-for", "insights-hotspots-view")).envelope.pybuild_surfaces(line 151) —subsystembranch present.target_resolve.pyis_resolvable(line 45) —subsystembranch present implementing the subsystem ref grammar (below).generate.pyinvalid-kind error message (line 143) — derives the taxonomy string fromsorted(TARGET_KINDS)dynamically (no hardcoded string to update;subsystemflows in automatically).- Subsystem ref grammar (state explicitly): a
subsystem:<name>ref resolves iff<name>is a key inscripts/plan_corpus/schemas.py:1845BUG_SUBSYSTEM_TO_CRATES(typeck,codegen,parse,eval,arc,canon,runtime,diagnostic,fmt,registry, plus the exempt-tooling keysharness,tooling,scripts,docs,skills).is_resolvable("subsystem", name)already returnsname in BUG_SUBSYSTEM_TO_CRATES(target_resolve.py:45, present). The resolved objective symbol set for a subsystem target is the union of symbols owned by that subsystem’s crates (resolved via per-cratefile-symbolsper thesubsystem:<name>resolver inw-18edfbb5). The existingselect_bug_clusteralready consumes thesubsystemstring againstb.subsystem='{sub}'attiers.py:254, so the cluster kwarg is wired; the remaining work is thew-18edfbb5resolver_fn objective-set entry, not theis_resolvablebranch.
- Reconcile
Items
- Production per-kind objective-symbol resolver: implement real resolution of
bug:/plan-section:/diff:/subsystem:target refs to objective symbol sets, naming the intel-graph edge per kind (no hand-wave; the resolver is executable-as-written):bug:<id>-> symbols via theMENTIONS_CODEedge on the plan/bug DAG (:PlanBugNode-[:MENTIONS_CODE]-> symbol, per CLAUDE.md §Intelligence Graph). The objective set is the union of symbols the bug node mentions; query throughscripts/intel-query.sh(the canonical graph wrapper) so the resolver degrades gracefully when the graph is down.plan-section:<id>-> symbols via the sameMENTIONS_CODEedge from the section node (HAS_SECTION/HAS_SUBSECTIONlocates the node;MENTIONS_CODEyields its symbols). Objective set = union of symbols the section mentions.diff:<ref>-> symbols via changed-file -> owning-symbol resolution in a SINGLE batch query (no per-file shell-out loop): (1) enumerate the diff’s changed-file set in ONE call —scripts/intel-query.sh diff-context [--since <ref>|--staged](intel-query.sh:122) returns the changed-file set graph-side, falling back togit diff --name-only <ref>for a SHA/range when diff-context is unavailable; (2) resolve the WHOLE changed-file set’s owning symbols in ONE batch graph read — a singlescripts/intel-query.sh cypher "<query>"(read-only MATCH/RETURN; surfaces.pyrun_cypherrejects any write token) returning the declarations for the entire changed-file set, NOTfile-symbolsinvoked per file in a loop (the per-file loop is theWASTE:performanceshape this avoids); (3) the batch result IS the objective set. Thedependency-graphtier then expands byCALLSadjacency at tier-assembly time — the resolver’s job ends at the changed-file -> owning-symbol union. Route every query throughscripts/intel-query.shso the resolver degrades gracefully when the graph is down.subsystem:<name>-> symbols via crate-membership + a SINGLE batch file-symbols query (no per-crate shell-out loop): (1) look up the subsystem’s crate list —BUG_SUBSYSTEM_TO_CRATES[<name>]fromscripts/plan_corpus/schemas.py:1845(the canonical subsystem->crates map;<name>validated bytarget_resolve.is_resolvable("subsystem", name)which is already wired); (2) resolve the union of all those crates’ symbols in ONE batch graph read — a singlescripts/intel-query.sh cypher "<query>"returning declarations for the whole crate-path set (a read-only MATCH/RETURN over the crate source roots), NOTfile-symbolsinvoked per crate in a loop; (3) the batch result IS the objective set. Route every query throughscripts/intel-query.shfor graceful degradation.- Make the production resolver the DEFAULT, not an injected seam. The production
ResolverFnlives in a new module-level functionsurfaces.production_resolver(kind, ref) -> list[str](alongsidesurfaces.resolve_objective_symbolsat surfaces.py:154-172; it routes the four per-kind arms above throughscripts/intel-query.shper theResolverFntype at surfaces.py:151).generate()(generate.py:113) andbuild_package()(generate.py:45) DEFAULTresolver_fntosurfaces.production_resolverwhen the caller passesNone— so the real CLI path (_cmd_generate,scripts/intel_package_runtime/__main__.py:35) ANDheal._regenerate_and_persist(heal.py:124, which threads only{out_dir, query_fn, status_fn}and never a resolver_fn) auto-resolve targets WITHOUT an injected seam. The injectedresolver_fnparameter STAYS as a test-only override seam; the default wiring is the incident fix that stopssurfaces.resolve_objective_symbols’s injected-only path from being the sole wired path. With the default in place,build_packagealways reaches the dossier branch (generate.py:74) for a resolvable target, never the legacy counts-manifest branch. - Populate the defect render block from the bug source, two-armed by plan-dir presence.
render.py:387-394currently bindsdefectwithrepro=None, divergence_rows=[], approach=None, table_headers=[]for ALL targets — a None-guarded EMPTY block. The transport: a defect-population step inenvelope.build_dossier(envelope.py:221) reads the bug source and writes the parsed fields ontodossier["defect"]alongside (NOT inside) theMENTIONS_CODEsymbol resolution;render.build_pkg_context(render.py:136) then readsdossier["defect"]into the render-contextdefectdict at render.py:387-394 instead of binding the None/[]defaults. A defect-population step inbuild_dossieris the cleaner site than aresolve_defect()arm of the symbol resolver — symbol resolution yields the objective set, defect population yields prose+table, two distinct outputs. The bug source has TWO arms (verified: the canonical example bug BUG-05-010 has NO plan dir on disk):- WHEN the bug’s plan dir at
bug-tracker/plans/BUG-XX-NNN/content/is PRESENT (rich source):repro<- the reproduction/symptom prose incontent/overview/mission.md;divergence_rows+table_headers<- the divergence table incontent/root-cause-analysis--s-*.md;approach<- the consensus fix prose incontent/fix-consensus--s-*.md. - ELSE (aggregate-only bug like BUG-05-010, no plan dir): fall back to the bug’s
BugTrackerEntryinbug-tracker/open-bugs.json/closed-bugs.json(the aggregate entry, keysid, subsystem, severity, title, status, plan_dir, found_date, resolved_date, repro):repro<- the entry’sreprofield (ortitlewhenreprois null);approach<- left None (no consensus exists pre-fix);divergence_rows<-[]withtable_headers[](the divergence table is RCA-only). This arm STILL produces a populated## 1. The defectsection — repro + the subsystem/severity/status header all render from the aggregate entry. divergence_rowsshape MUST matchpackage.md.j2:45-49: a LIST of row-LISTS, each inner list aligned positionally totable_headers(rendered{{ row | join(' | ') }}), NOT a two-key{expected, actual}dict —table_headerscarries the RCA table’s actual column labels (e.g. the four-columnSurface | File | Reports alignment as | Directionshape inintel-package-example.md:37-41), and eachdivergence_rowsentry is one full table row of cell strings in column order. The defect-population step threads these ontodossier["defect"]so## 1. The defect(intel-package-example.md:31-49) renders with real content. Non-bug targets keep the None-guarded empty block (the guard key is absent for them, so the section is suppressed regardless). This populated defect block is what closes sc-0012’s approved-example conformance — the guard-key injection inw-605bd83bmakes the section RENDER; this population makes it render with CONTENT.
- WHEN the bug’s plan dir at
- Completed-by tests s-15e599fa.
sc-0012 verification note
sc-0012 (owned by this section) drives the REAL production entry point per layer-coverage.md §1 L12 — NOT a seam-injected resolver_fn. The completion phase MUST verify ALL of the following against the real path:
- CLI no-injection probe (primary).
python -m scripts.intel_package_runtime generate --target bug:BUG-05-010with NO injected resolver_fn. Assert: non-empty dossier-genrepackage.md; zero counts-manifest substrings (the dossier branch, not the legacybuild_surfacesbranch); adjacency rows present; DIG DEEPER block present; exactly one pinned VERDICT line. - Approved-example conformance — explicit defect assertion. Assert the
bug:dossier renders the bug-only## 1. The defectsection (intel-package-example.md:31) WITH POPULATED content — repro text, divergence rows, and approach all non-empty (per thew-18edfbb5defect-block population). A dossier that omits the defect section, or renders it empty (the pre-fixrender.py:387-394None-bind shape), FAILS this assertion. This is the load-bearing approved-example-conformance check; an assertion that passes on a defect-less dossier is insufficient. - Heal-path probe.
heal._regenerate_and_persistinvoked with NO injected resolver_fn (kwargs limited to{out_dir, query_fn, status_fn}as the production caller threads them). Assert the heal-regenerated package matches the dossier-genre shape — proving the resolver_fn is wired at the heal entry point, not only at the CLI entry point. - Per-kind CLI probes. Run
generate --target <ref>for each kept kind with no injected resolver_fn, using these CONCRETE verified-resolvable refs (one per kind):bug:BUG-05-010— the canonical example bug (subject ofintel-package-example.md; aggregate-only, no plan dir — exercises the cure-1 fallback arm).plan-section:intel-package-dossier-rebuild/tests--s-15e599fa— a real section of this plan (sibling content filetests--s-15e599fa.mdexists on disk).diff:HEAD~5..HEAD— a real git range ref (resolves via thediff-context/git diffchanged-file path of the cure-4 resolver).subsystem:typeck— a real key inBUG_SUBSYSTEM_TO_CRATES(scripts/plan_corpus/schemas.py:1845, maps toori_types, ori_ir).symbol-set:optimize_result_repr,build_result_variants— the example objective symbols (ori_repr::layout::niche::optimize_result_repr+build_result_variants, named inintel-package-example.md:58-59;symbol-setref carries them verbatim comma-separated). Assert each produces a dossier-genrepackage.mdwhose active-tier blocks matchactive_tiers(kind)fromw-605bd83b(defect present ONLY forbug:BUG-05-010; the diff active set non-empty per the matrix row).