Iterations 4-5 made the context pack SURFACE Docker mounts and
service/storage facts; this closes the CAPTURE side so the analyzer
actually produces them. The workload analysis prompt asked for config
dirs but never for how to restart/reload the service or the specific
files a user edits. Add: (q9) how the service is managed/restarted; an
instruction to put specific key files (configuration.yaml,
automations.yaml, postgresql.conf) in config_paths rather than just the
parent dir; and an instruction to record the service-control mechanism
as a 'service'-category fact. Directly serves the 'reload my automation'
case.
Test pins both instructions in the built deep prompt; teeth-checked.
Build + vet + gofmt clean, full servicediscovery package green.
filterImportantFacts kept only hardware/dependency/security/version
facts, dropping 'service' and 'storage'. But a service fact (e.g. the
systemd unit) is exactly how the Assistant restarts/reloads a workload,
and a storage fact (the backing dataset/disk) is where its data lives —
neither is redundant with the CLI/path sections, and both are what a
real question like 'the database is slow, restart it' needs. Add both to
the priority categories.
Corpus: add a postgresql LXC cell whose required context includes the
systemd unit and data filesystem. Teeth-checked — the case fails without
the filter change. Build + vet + gofmt clean, full servicediscovery
package green.
Two-part start of the Discovery->Assistant context-completeness work.
1. FormatForAIContext (the context pack Chat/Patrol consume) dropped
DockerMounts, even though the model captures them. A container path
like /config is meaningless for editing or backing up persistent files
without its host source, so the Assistant could not act on a real
request like 'edit my blinds automation on the host'. Surface the
host -> container mapping (with read-only marker).
2. Add scenario_corpus_test.go — the verifiable oracle for the goal:
given a realistic discovered workload, the context pack must surface
everything the Assistant needs to answer a concrete user question with
zero re-explanation. Seeded with Home Assistant (LXC: pct exec +
automations.yaml + log; Docker: docker exec + bind-mount source). The
corpus grows one service-type cell at a time; a missing substring is a
concrete gap to close in the analyzer or formatter.
Teeth-checked: the Docker case fails without change #1. Build + vet clean,
full servicediscovery package green.
The tab-wide banner says 'configure a provider before scanning', yet all
four 'Run Discovery' affordances stayed clickable into a guaranteed
failure (discovery uses the AI to analyze evidence). Route every run
button through canTriggerDiscovery, now also requiring a configured
provider, so the action matches the banner. Command/connectivity gaps
are surfaced separately and intentionally not blocked here.
Tests: existing manual-run test configures a provider so its button
stays enabled; new test asserts the run action is disabled (and trigger
never fires) without a provider. Also hardened afterEach to reset
getDiscoveryInfo between tests — clearAllMocks does not reset
mockResolvedValue impls, so a provider mock would otherwise bleed into
later no-provider cases. Discovery 16/16, type-check + lint + prettier
clean; full suite 6018 pass (2 pre-existing guardrail failures).
The AI-provider prerequisite only rendered inside the agent-only
connection-status trio, so opening Discovery on a VM/container with no
provider configured gave no hint the feature could not run — the
silently on-but-useless dead end. Promote it to a tab-wide banner driven
by the same canonical readiness verdict, styled to match the sibling
'disabled' banner, shown for every resource type. Remove the now-
redundant provider banner from the agent trio (which keeps commands ->
connectivity).
Test: new case asserts a non-agent resource surfaces the provider
prerequisite. Discovery 15/15, type-check + full lint clean; the 2
unrelated guardrail failures pre-exist on the branch.
Pure formatting: prettier collapses the readiness-trio Show condition to
a single line. No behavior change; follow-up to c2c5ce048 (eslint passed
at commit time but prettier format was not enforced by the hook).
Discovery re-derived its prerequisite state (disabled / provider /
commands / connectivity) ad hoc across surfaces, so the agent
connection-status banners could nag about commands while the more
fundamental gap — no AI provider configured — went unsaid.
Wire the (previously orphaned, unwired) computeDiscoveryReadiness module
in as the canonical verdict: useDiscoveryTabState now derives
aiProviderConfigured + a single discoveryReadiness memo, and the
DiscoveryTab connection-status block renders from readiness().status,
surfacing the most-fundamental missing prerequisite first. Adds the
missing needs_ai_provider banner. The green 'connected' banner stays
literal by design (the verdict treats unknown command state as ready).
Tests: existing command-state cases now configure a provider to reach
those states; new case asserts the provider prerequisite precedes
command guidance. Full frontend suite + type-check + lint green (the 2
unrelated guardrail failures pre-exist on the branch, proven via scoped
stash).