- the unknown runtime schema path error now states that canonical paths
contain dots and must be a single argument while space-separated tokens
resolve as a CLI path; help text and docs only reach agents that consult
them, the error is the one surface guaranteed to be seen at failure time
- the app trust diagnostic comment is shortened to the durable constraint
(do not pin absolute Catalog-size counts) instead of narrating the change
- NewDeliveryToolSearchEngine's doc comment notes the memo serves long-lived
hosts; the shipped schema search command rebuilds per invocation through
NewDeliveryToolSearchEngineWithConfig
The diagnostic test pinned absolute counts from one Catalog generation:
1123 intent cases, Recall@5 == 990/1123, 1098 tools and the 402/721
language slices. Merging main grew the Catalog to 1121 tools, so the
population became 1147/407/740 and the test failed as a size drift
rather than as a trust regression.
- the absolute counts are removed; the observed intent, language-slice
and context values are logged for CI forensics and the headline numbers
stay in the generated comparison JSON
- identity coverage is still enforced exhaustively, but the expected
count is derived from report.Context.ToolCount instead of a literal
- the trust contract that does not move with Catalog size stays a hard
gate: every identity pass rate == 1, alias cases non-zero, all four
integrity counters == 0, zero-result rate == 0, non-empty language
slices and ReductionVsFullSchema >= 0.99
- SearchSubqueries returned a nil candidate slice on the
decomposed_exact_filtered refusal, so that one strategy encoded
"candidates":null while every other path encoded []; the refusal now
carries an empty slice and a marshal assertion pins the wire shape
- the memoized delivery engine was never invalidated: it indexes one
Catalog generation and caches its source/surface hashes, but
RegisterSchemaSourceRoot -> resetDeliverySchemaCatalogState left the
memo installed, so a re-registered root could be served stale hashes.
Catalog delivery reset now clears it, with a ForTest wrapper and a
regression test for the rebuild
- dangerous filter Unicode is rejected before the effect vocabulary and
Catalog product checks, so a control/Bidi character returns
dangerous_filter_unicode instead of being echoed back through
invalid_effect; the filter list is an ordered slice, not a map, so the
reported field name is deterministic
- dws schema help and RFC 5.8 record the path-form boundary: multi-token
args resolve as a CLI path, a canonical path must stay one argument
- --explain and ToolSearchScoreBreakdown declare that the reported score
is the raw value while ordering uses the quantized key
- --limit/--candidate-limit help state that 0 means "use the default",
which was already the behavior but read as an asymmetry against the
rejected negative values
- bootstrap seeds become named constants and are published in both
evaluation reports (bootstrap_samples/bootstrap_seed/
recovery_bootstrap_seed) so an interval is reproducible without
reading the source
- dingtalk-shared documents the cross-product summary --dry-run flag and
that its command list is a plan, not business data
The RFC, source-implementation research, GitHub architecture research,
ranking evaluation report, 2026-08-14 optimization plan and ten-round
review record were six separate files that cross-linked each other for
the same decision chain. They are merged into
docs/tool-search-progressive-discovery.md as Part 1..6, ordered
decision -> research -> evidence -> plan -> review record.
- cross-file links become in-document "本文档 Part N" pointers; the five
remaining relative links (source and evaluator paths) still resolve
- section content is unchanged apart from one addition: 5.8 Inspect now
records the path-form boundary (multi-token args resolve as a CLI path;
a canonical path must be passed as a single argument), matching the
dws schema help text