Expand description
Resolve & search (decided resolve, decided find) — a port of
src/asdecided/services/resolve.py (+ the index construction in
src/asdecided/services/index.py), per PORT-CONTRACT.d/06.
Landmines reproduced here (contract §15):
- ASCII-only tokenizer (§1) vs full-Unicode casefold/strip in exact
resolution (§3) and the
--tagfacet (§5.2). - Corpus statistics are corpus-global (all types, unknowns included) even
under
--type/--tag; ranks are over the matched set only (§6). - Duplicate query tokens are NOT deduped:
dfincrements per occurrence and the per-term score adds per occurrence (§7.1). - BM25F float operation ORDER is normative (§7): weighted_tf accumulates
in
id, title, path, heading, body, tagsfield order with zero-tf fields skipped; score accumulates in query-token order;idf = ln(1 + (n - d + 0.5)/(d + 0.5))via plain f64 ops (not ln_1p). - Competition ranks share on EXACT f64 equality (§8).
- Sort key is
(-py_round(fused, 12), path); the stored fused value stays unrounded; evidence carriespy_round(., 6)(§9–10).
Structs§
- Corpus
Stats - Corpus-global BM25 statistics (all entries, unknowns included).
- Evidence
- The
--explainevidence object plus the unrounded score components (bm25_raw/fused_raware not serialized; they exist so conformance tests can assert exact f64 bit equality against the oracle). - Field
Tokens - Flat per-field token vectors, one per scorable field.
- Index
Entry - One searchable row of the repository index.
- Recency
- The git-derived recency join (
Staleness.to_dict()shape). - Resolution
Result - Outcome of one exact-ID lookup (
ResolutionResult). - Resolved
Artifact - One resolved artifact / search match (
ResolvedArtifact). - Search
Result - Outcome of one repository search (
SearchResult).
Constants§
Functions§
- artifact_
status agent_rules.artifact_status: first non-empty stripped line of## Status.- build_
index build_repository_index(directory, recursive).artifacts— the searchable index in corpus-walk (sorted-path) order, inbound counts included.- entry_
is_ retired entry_is_retired(entry)— thelive_onlyfacet (ADR-113): re-read the entry’s## Statusfrom its file and test it against the type’sretired_statusset (is_retired_status). Unreadable/unknown ⇒ live.- find_
artifacts find_artifacts(directory, query, artifact_type, recursive, tags, live_only).- find_
decisions find_decisions(directory, topic, recursive): the type-restricted tiered search, post-filtered to live decisions (ranks keep their gaps — evidence is computed over all matched decisions including non-live ones).- index_
from_ items - is_
retired_ status agent_rules.is_retired_status(artifact_type, status)(ADR-113): spec-driven retirement for every typed artifact. An unknown type retires nothing; an empty status is never retired.- resolve_
artifact resolve_artifact(directory, artifact_id, recursive). The oracle’s identity-only walk (_identity_index) leaves sections/graph/tags at their empty defaults; resolve output reads only id/type/title/path, so those fields never surface (resolve JSON never gains a “tags” key).- resolve_
in_ index resolve_in_index(entries, artifact_id): full-Unicode strip + casefold on the query, casefolded exact equality against every alias.- search_
index search_index(entries, query, artifact_type, tags)— matching, corpus stats, BM25F + RRF ranking, and the(-round(fused,12), path)sort.- search_
index_ filtered search_index(..., live_only=...)(ADR-113, additive): withlive_only, retired artifacts of every type are dropped from the matched set BEFORE scoring, so competition ranks are computed among the live survivors. Withlive_only=falsethe result is byte-identical tosearch_index.- stats_
for - Corpus-global statistics for one query over
entries— the conformance vector surface (gen_vectors_resolve.pypinsn/df/avglen). - tokenize
tokenize(text): split on runs of non-[0-9A-Za-z](every non-ASCII char is a separator), split each piece at ASCII lowercase→uppercase seams, then casefold (pure-ASCII pieces: exactlyA-Z -> a-z).