Repair live unified search corpus runtime
This commit is contained in:
@@ -2223,6 +2223,10 @@ services:
|
||||
ADVISORYAI__KnowledgeSearch__ConnectionString: *postgres-connection
|
||||
ADVISORYAI__KnowledgeSearch__FindingsAdapterEnabled: "true"
|
||||
ADVISORYAI__KnowledgeSearch__FindingsAdapterBaseUrl: "http://scanner.stella-ops.local"
|
||||
ADVISORYAI__KnowledgeSearch__VexAdapterEnabled: "true"
|
||||
ADVISORYAI__KnowledgeSearch__VexAdapterBaseUrl: "http://concelier.stella-ops.local"
|
||||
ADVISORYAI__KnowledgeSearch__PolicyAdapterEnabled: "true"
|
||||
ADVISORYAI__KnowledgeSearch__PolicyAdapterBaseUrl: "http://policy-gateway.stella-ops.local"
|
||||
Router__Enabled: "${ADVISORYAI_ROUTER_ENABLED:-true}"
|
||||
Router__Messaging__ConsumerGroup: "advisoryai"
|
||||
ports:
|
||||
@@ -2261,6 +2265,10 @@ services:
|
||||
ADVISORYAI__KnowledgeSearch__ConnectionString: *postgres-connection
|
||||
ADVISORYAI__KnowledgeSearch__FindingsAdapterEnabled: "true"
|
||||
ADVISORYAI__KnowledgeSearch__FindingsAdapterBaseUrl: "http://scanner.stella-ops.local"
|
||||
ADVISORYAI__KnowledgeSearch__VexAdapterEnabled: "true"
|
||||
ADVISORYAI__KnowledgeSearch__VexAdapterBaseUrl: "http://concelier.stella-ops.local"
|
||||
ADVISORYAI__KnowledgeSearch__PolicyAdapterEnabled: "true"
|
||||
ADVISORYAI__KnowledgeSearch__PolicyAdapterBaseUrl: "http://policy-gateway.stella-ops.local"
|
||||
volumes:
|
||||
- *cert-volume
|
||||
networks:
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
# Sprint 20260309-013 - AdvisoryAI Live Unified Search Corpus Runtime Repair
|
||||
|
||||
## Topic & Scope
|
||||
- Repair the live unified-search corpus gap exposed after the full rebuild and canonical route sweep: search-driven pages render, but several answer lanes report zero indexed chunks or insufficient evidence.
|
||||
- Fix the real runtime contract in `src/AdvisoryAI/**` and compose wiring so published containers can resolve the packaged corpus and live adapters ingest findings, VEX, and policy data consistently.
|
||||
- Keep the work scoped to AdvisoryAI runtime/search surfaces plus the minimal compose/docs coordination required to make the deployed stack converge correctly.
|
||||
- Working directory: `src/AdvisoryAI/`.
|
||||
- Allowed coordination edits: `devops/compose/docker-compose.stella-ops.yml`, `docs/modules/advisory-ai/**`, `docs/operations/unified-search-operations.md`, `docs/implplan/SPRINT_20260309_013_AdvisoryAI_live_unified_search_corpus_runtime_repair.md`, `src/Web/StellaOps.Web/output/playwright/**`.
|
||||
- Expected evidence: focused AdvisoryAI test runs against the individual test `.csproj`, rebuilt `advisory-ai-web` and `advisory-ai-worker` images, redeployed compose services, refreshed live Playwright search artifacts.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on `SPRINT_20260309_001_Platform_scratch_setup_bootstrap_restore.md` for the rebuilt stack baseline and `SPRINT_20260309_012_Router_live_quota_scope_and_notify_dispatch_repairs.md` for the clean `111/111` route-presence sweep.
|
||||
- Safe parallelism: stay out of unrelated frontend/search UX changes outside `src/AdvisoryAI/**`; only add the minimal compose wiring needed for AdvisoryAI runtime configuration.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `AGENTS.md`
|
||||
- `docs/code-of-conduct/CODE_OF_CONDUCT.md`
|
||||
- `docs/qa/feature-checks/FLOW.md`
|
||||
- `docs/modules/platform/architecture-overview.md`
|
||||
- `docs/modules/advisory-ai/architecture.md`
|
||||
- `docs/modules/advisory-ai/knowledge-search.md`
|
||||
- `docs/operations/unified-search-operations.md`
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### LIVE-AIAI-013-001 - Restore published unified-search corpus packaging
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Developer, Test Automation
|
||||
Task description:
|
||||
- Repair the AdvisoryAI published-image contract so the container carries the full repo-shaped unified-search corpus at the configured source-relative paths. The current image only packages a subset of snapshots, leaving graph, OpsMemory, timeline, and scanner answer lanes permanently unready in live deployments.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Published AdvisoryAI output includes all unified-search snapshot files under `src/AdvisoryAI/StellaOps.AdvisoryAI/UnifiedSearch/Snapshots/`.
|
||||
- [x] AdvisoryAI tests cover runtime publish-layout resolution for all default unified snapshot paths.
|
||||
- [x] Snapshot-only adapters use the repository-aware resolver rather than assuming `.` is the repository root.
|
||||
|
||||
### LIVE-AIAI-013-002 - Wire live VEX and policy adapters in compose
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Developer, QA
|
||||
Task description:
|
||||
- Extend the live compose configuration so both AdvisoryAI hosts ingest VEX and policy data from the deployed Concelier and Policy Gateway services instead of silently relying on missing or stale fallback snapshots.
|
||||
|
||||
Completion criteria:
|
||||
- [x] `advisory-ai-web` runtime env sets findings, VEX, and policy adapter base URLs.
|
||||
- [x] `advisory-ai-worker` runtime env sets findings, VEX, and policy adapter base URLs.
|
||||
- [x] AdvisoryAI/search docs describe the required live adapter configuration.
|
||||
|
||||
### LIVE-AIAI-013-003 - Rebuild, redeploy, and reverify live search-driven pages
|
||||
Status: DONE
|
||||
Dependency: LIVE-AIAI-013-001, LIVE-AIAI-013-002
|
||||
Owners: Developer, QA
|
||||
Task description:
|
||||
- Rebuild the touched AdvisoryAI images, redeploy them into the existing stack, and rerun the live Playwright search/action sweep to verify that the previously corpus-unready answer lanes now return grounded or at least populated results from the repaired corpus.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Focused AdvisoryAI test runs pass from the individual test project.
|
||||
- [x] `advisory-ai-web` and `advisory-ai-worker` are rebuilt and redeployed from the current source.
|
||||
- [x] Live search artifacts are refreshed after the redeploy and show the repaired answer/corpus state on the affected pages.
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-03-09 | Sprint created after the full rebuild/redeploy and live changed-surface sweep exposed a deeper AdvisoryAI runtime issue: search-driven pages loaded but several answer lanes remained corpus-unready because the published image carried only a partial unified snapshot set and compose only wired the findings live adapter. | Developer |
|
||||
| 2026-03-09 | Published the full unified snapshot corpus into the AdvisoryAI image at the documented source-relative paths, switched graph/opsmemory/timeline/scanner adapters to the repository-aware resolver, and added runtime-publish coverage plus focused live-adapter/integration test evidence (`23/23` via the xUnit runner against the rebuilt test assembly). | Developer |
|
||||
| 2026-03-09 | Rebuilt and redeployed `advisory-ai-web` and `advisory-ai-worker`, verified runtime env and packaged snapshots inside the live container, rebuilt the knowledge/unified indexes (`domains=8`, `chunks=22`), and rechecked mission board, advisories/VEX, and policy overview with authenticated Playwright at `src/Web/StellaOps.Web/output/playwright/live-search-runtime-repair-recheck.json`. | QA |
|
||||
|
||||
## Decisions & Risks
|
||||
- Decision: preserve the documented source-relative asset contract instead of changing defaults to ad hoc published-only paths. The container image must look repo-shaped under `/app` so the same defaults work in source and published runs.
|
||||
- Decision: fix live VEX and policy ingestion in compose/runtime rather than masking the issue with UI fallback copy.
|
||||
- Risk: `devops/compose/docker-compose.stella-ops.yml` is a shared file touched by other workstreams. Limit edits strictly to the AdvisoryAI env block.
|
||||
- Evidence: live container verification now shows all packaged snapshot files under `/app/src/AdvisoryAI/StellaOps.AdvisoryAI/UnifiedSearch/Snapshots/`, and the AdvisoryAI logs report non-zero rebuild/refresh counts for findings, graph, opsmemory, platform, policy, scanner, timeline, and vex.
|
||||
|
||||
## Next Checkpoints
|
||||
- 2026-03-09: land packaging/runtime repair and live adapter wiring, then rerun focused AdvisoryAI tests plus live Playwright verification.
|
||||
@@ -133,10 +133,15 @@ Implemented in `src/AdvisoryAI/StellaOps.AdvisoryAI/KnowledgeSearch/KnowledgeSea
|
||||
- Unified ingestion adapters for findings/vex/policy now use live upstream service payloads as primary source, with deterministic snapshot fallback only when upstream endpoints are unavailable or unconfigured.
|
||||
- Live adapters: `FindingsSearchAdapter`, `VexSearchAdapter`, `PolicySearchAdapter`.
|
||||
- Platform catalog remains a deterministic snapshot projection via `PlatformCatalogIngestionAdapter`.
|
||||
- Live compose/runtime must wire all three adapter bases together: `AdvisoryAI:KnowledgeSearch:FindingsAdapterBaseUrl`, `...:VexAdapterBaseUrl`, and `...:PolicyAdapterBaseUrl`. Leaving only findings configured produces grounded findings cards while VEX/policy answers degrade to `corpus_unready`/zero-chunk responses.
|
||||
- Default snapshot fallback paths:
|
||||
- `src/AdvisoryAI/StellaOps.AdvisoryAI/UnifiedSearch/Snapshots/findings.snapshot.json`
|
||||
- `src/AdvisoryAI/StellaOps.AdvisoryAI/UnifiedSearch/Snapshots/vex.snapshot.json`
|
||||
- `src/AdvisoryAI/StellaOps.AdvisoryAI/UnifiedSearch/Snapshots/policy.snapshot.json`
|
||||
- `src/AdvisoryAI/StellaOps.AdvisoryAI/UnifiedSearch/Snapshots/graph.snapshot.json`
|
||||
- `src/AdvisoryAI/StellaOps.AdvisoryAI/UnifiedSearch/Snapshots/opsmemory.snapshot.json`
|
||||
- `src/AdvisoryAI/StellaOps.AdvisoryAI/UnifiedSearch/Snapshots/timeline.snapshot.json`
|
||||
- `src/AdvisoryAI/StellaOps.AdvisoryAI/UnifiedSearch/Snapshots/scanner.snapshot.json`
|
||||
- Ranking determinism:
|
||||
- Freshness boost is disabled by default and only applies when `UnifiedFreshnessBoostEnabled` is explicitly enabled.
|
||||
- Ranking no longer depends on ambient wall-clock time unless that option is enabled.
|
||||
@@ -383,6 +388,7 @@ Notes:
|
||||
- Set `AdvisoryAI__KnowledgeSearch__RepositoryRoot` only when you are running the service from a non-standard layout or a packaged binary tree that is not inside the repository.
|
||||
- `stella advisoryai index rebuild` and `stella search index rebuild` invoke authenticated backend endpoints. For a local source-checkout verification lane without a signed-in CLI session, use `sources prepare` via CLI and the direct HTTP rebuild calls above with explicit `X-StellaOps-*` headers.
|
||||
- Compose/runtime requirement: the published AdvisoryAI service image must carry a repo-shaped local corpus under its app content root so `POST /v1/advisory-ai/index/rebuild` can resolve `docs/**`, `devops/compose/openapi_current.json`, and `src/AdvisoryAI/StellaOps.AdvisoryAI/KnowledgeSearch/*.json` even when the source checkout is not mounted into the container. If those assets are absent, live search on `stella-ops.local` degrades to partial unified rows only and documentation/Doctor/API answers disappear.
|
||||
- The published app content root must also carry the full unified snapshot corpus under `src/AdvisoryAI/StellaOps.AdvisoryAI/UnifiedSearch/Snapshots/*.json`; packaging only findings/VEX/policy snapshots leaves graph, OpsMemory, timeline, and scanner answer lanes permanently corpus-unready in the live shell.
|
||||
|
||||
### CLI setup in a source checkout
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ Runbook for AdvisoryAI unified search setup, operations, troubleshooting, perfor
|
||||
## Setup
|
||||
1. Configure `AdvisoryAI:KnowledgeSearch:ConnectionString`.
|
||||
2. Configure `AdvisoryAI:UnifiedSearch` options.
|
||||
3. For live compose/runtime, set `AdvisoryAI:KnowledgeSearch:FindingsAdapterBaseUrl`, `...:VexAdapterBaseUrl`, and `...:PolicyAdapterBaseUrl` together so findings, VEX, and policy ingest from live services instead of partial fallback snapshots.
|
||||
4. Ensure the published AdvisoryAI image carries the repo-shaped local corpus under `/app`, including `src/AdvisoryAI/StellaOps.AdvisoryAI/UnifiedSearch/Snapshots/{findings,vex,policy,graph,opsmemory,timeline,scanner}.snapshot.json`.
|
||||
3. Ensure model artifact path exists when `VectorEncoderType=onnx`:
|
||||
- default: `models/all-MiniLM-L6-v2.onnx`
|
||||
4. Rebuild indexes in order when verifying live search quality:
|
||||
@@ -109,6 +111,7 @@ Example:
|
||||
- Verify `UnifiedSearch.Enabled` and tenant flag `Enabled`.
|
||||
- Run index rebuild and check chunk count.
|
||||
- If suggestions also fail, verify both rebuild steps were run in order and re-check with a known live query such as `database connectivity`.
|
||||
- If only findings answer lanes work while VEX/policy/graph/OpsMemory remain corpus-unready, verify the published snapshot files exist under `/app/src/AdvisoryAI/StellaOps.AdvisoryAI/UnifiedSearch/Snapshots/` and confirm the VEX/policy adapter base URLs are configured in runtime env.
|
||||
|
||||
### Symptom: poor semantic recall
|
||||
- Verify `VectorEncoderType` and active encoder diagnostics.
|
||||
|
||||
@@ -8,6 +8,15 @@ internal sealed record KnowledgeSearchRepositoryRootResolution(
|
||||
internal static class KnowledgeSearchRepositoryRootResolver
|
||||
{
|
||||
public static string ResolvePath(KnowledgeSearchOptions options, string configuredPath)
|
||||
{
|
||||
return ResolvePath(options, configuredPath, Directory.GetCurrentDirectory(), AppContext.BaseDirectory);
|
||||
}
|
||||
|
||||
internal static string ResolvePath(
|
||||
KnowledgeSearchOptions options,
|
||||
string configuredPath,
|
||||
string? currentDirectory,
|
||||
string? appBaseDirectory)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(options);
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(configuredPath);
|
||||
@@ -17,7 +26,7 @@ internal static class KnowledgeSearchRepositoryRootResolver
|
||||
return Path.GetFullPath(configuredPath);
|
||||
}
|
||||
|
||||
var repositoryRoot = Resolve(options);
|
||||
var repositoryRoot = Resolve(options, currentDirectory, appBaseDirectory);
|
||||
return Path.GetFullPath(Path.Combine(repositoryRoot.Path, configuredPath));
|
||||
}
|
||||
|
||||
|
||||
@@ -95,15 +95,31 @@
|
||||
</None>
|
||||
<None Update="UnifiedSearch/Snapshots/findings.snapshot.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<TargetPath>UnifiedSearch/Snapshots/findings.snapshot.json</TargetPath>
|
||||
<TargetPath>src/AdvisoryAI/StellaOps.AdvisoryAI/UnifiedSearch/Snapshots/findings.snapshot.json</TargetPath>
|
||||
</None>
|
||||
<None Update="UnifiedSearch/Snapshots/vex.snapshot.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<TargetPath>UnifiedSearch/Snapshots/vex.snapshot.json</TargetPath>
|
||||
<TargetPath>src/AdvisoryAI/StellaOps.AdvisoryAI/UnifiedSearch/Snapshots/vex.snapshot.json</TargetPath>
|
||||
</None>
|
||||
<None Update="UnifiedSearch/Snapshots/policy.snapshot.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<TargetPath>UnifiedSearch/Snapshots/policy.snapshot.json</TargetPath>
|
||||
<TargetPath>src/AdvisoryAI/StellaOps.AdvisoryAI/UnifiedSearch/Snapshots/policy.snapshot.json</TargetPath>
|
||||
</None>
|
||||
<None Update="UnifiedSearch/Snapshots/graph.snapshot.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<TargetPath>src/AdvisoryAI/StellaOps.AdvisoryAI/UnifiedSearch/Snapshots/graph.snapshot.json</TargetPath>
|
||||
</None>
|
||||
<None Update="UnifiedSearch/Snapshots/opsmemory.snapshot.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<TargetPath>src/AdvisoryAI/StellaOps.AdvisoryAI/UnifiedSearch/Snapshots/opsmemory.snapshot.json</TargetPath>
|
||||
</None>
|
||||
<None Update="UnifiedSearch/Snapshots/timeline.snapshot.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<TargetPath>src/AdvisoryAI/StellaOps.AdvisoryAI/UnifiedSearch/Snapshots/timeline.snapshot.json</TargetPath>
|
||||
</None>
|
||||
<None Update="UnifiedSearch/Snapshots/scanner.snapshot.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<TargetPath>src/AdvisoryAI/StellaOps.AdvisoryAI/UnifiedSearch/Snapshots/scanner.snapshot.json</TargetPath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -176,13 +176,7 @@ internal sealed class GraphNodeIngestionAdapter : ISearchIngestionAdapter
|
||||
|
||||
private string ResolvePath(string configuredPath)
|
||||
{
|
||||
if (Path.IsPathRooted(configuredPath))
|
||||
{
|
||||
return configuredPath;
|
||||
}
|
||||
|
||||
var root = string.IsNullOrWhiteSpace(_knowledgeOptions.RepositoryRoot) ? "." : _knowledgeOptions.RepositoryRoot;
|
||||
return Path.GetFullPath(Path.Combine(root, configuredPath));
|
||||
return KnowledgeSearchRepositoryRootResolver.ResolvePath(_knowledgeOptions, configuredPath);
|
||||
}
|
||||
|
||||
private static string BuildEntityKey(
|
||||
@@ -224,4 +218,3 @@ internal sealed class GraphNodeIngestionAdapter : ISearchIngestionAdapter
|
||||
return raw is not null && DateTimeOffset.TryParse(raw, out var timestamp) ? timestamp : null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -141,13 +141,7 @@ internal sealed class OpsDecisionIngestionAdapter : ISearchIngestionAdapter
|
||||
|
||||
private string ResolvePath(string configuredPath)
|
||||
{
|
||||
if (Path.IsPathRooted(configuredPath))
|
||||
{
|
||||
return configuredPath;
|
||||
}
|
||||
|
||||
var root = string.IsNullOrWhiteSpace(_knowledgeOptions.RepositoryRoot) ? "." : _knowledgeOptions.RepositoryRoot;
|
||||
return Path.GetFullPath(Path.Combine(root, configuredPath));
|
||||
return KnowledgeSearchRepositoryRootResolver.ResolvePath(_knowledgeOptions, configuredPath);
|
||||
}
|
||||
|
||||
private static string GuessSubjectType(string subjectRef)
|
||||
@@ -234,4 +228,3 @@ internal sealed class OpsDecisionIngestionAdapter : ISearchIngestionAdapter
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -139,13 +139,7 @@ internal sealed class ScanResultIngestionAdapter : ISearchIngestionAdapter
|
||||
|
||||
private string ResolvePath(string configuredPath)
|
||||
{
|
||||
if (Path.IsPathRooted(configuredPath))
|
||||
{
|
||||
return configuredPath;
|
||||
}
|
||||
|
||||
var root = string.IsNullOrWhiteSpace(_knowledgeOptions.RepositoryRoot) ? "." : _knowledgeOptions.RepositoryRoot;
|
||||
return Path.GetFullPath(Path.Combine(root, configuredPath));
|
||||
return KnowledgeSearchRepositoryRootResolver.ResolvePath(_knowledgeOptions, configuredPath);
|
||||
}
|
||||
|
||||
private static string? ReadString(JsonElement obj, string propertyName)
|
||||
@@ -187,4 +181,3 @@ internal sealed class ScanResultIngestionAdapter : ISearchIngestionAdapter
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -144,13 +144,7 @@ internal sealed partial class TimelineEventIngestionAdapter : ISearchIngestionAd
|
||||
|
||||
private string ResolvePath(string configuredPath)
|
||||
{
|
||||
if (Path.IsPathRooted(configuredPath))
|
||||
{
|
||||
return configuredPath;
|
||||
}
|
||||
|
||||
var root = string.IsNullOrWhiteSpace(_knowledgeOptions.RepositoryRoot) ? "." : _knowledgeOptions.RepositoryRoot;
|
||||
return Path.GetFullPath(Path.Combine(root, configuredPath));
|
||||
return KnowledgeSearchRepositoryRootResolver.ResolvePath(_knowledgeOptions, configuredPath);
|
||||
}
|
||||
|
||||
private static (string? EntityKey, string EntityType) ExtractEntity(string targetRef)
|
||||
|
||||
@@ -55,6 +55,39 @@ public sealed class KnowledgeSearchRepositoryRootResolverTests
|
||||
Assert.Equal(fixture.AppBaseDirectory, resolution.Path);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolvePath_points_all_default_unified_snapshot_paths_at_runtime_publish_corpus()
|
||||
{
|
||||
using var fixture = RuntimePublishLayoutFixture.Create();
|
||||
var knowledgeOptions = new KnowledgeSearchOptions();
|
||||
var unifiedOptions = new StellaOps.AdvisoryAI.UnifiedSearch.UnifiedSearchOptions();
|
||||
var unrelatedCurrentDirectory = Path.Combine(fixture.WorkspaceRoot, "outside");
|
||||
Directory.CreateDirectory(unrelatedCurrentDirectory);
|
||||
|
||||
var configuredPaths = new[]
|
||||
{
|
||||
knowledgeOptions.UnifiedFindingsSnapshotPath,
|
||||
knowledgeOptions.UnifiedVexSnapshotPath,
|
||||
knowledgeOptions.UnifiedPolicySnapshotPath,
|
||||
unifiedOptions.Ingestion.GraphSnapshotPath,
|
||||
unifiedOptions.Ingestion.OpsMemorySnapshotPath,
|
||||
unifiedOptions.Ingestion.TimelineSnapshotPath,
|
||||
unifiedOptions.Ingestion.ScannerSnapshotPath,
|
||||
};
|
||||
|
||||
foreach (var configuredPath in configuredPaths)
|
||||
{
|
||||
var resolved = KnowledgeSearchRepositoryRootResolver.ResolvePath(
|
||||
knowledgeOptions,
|
||||
configuredPath,
|
||||
unrelatedCurrentDirectory,
|
||||
fixture.AppBaseDirectory);
|
||||
|
||||
Assert.StartsWith(fixture.AppBaseDirectory, resolved, StringComparison.OrdinalIgnoreCase);
|
||||
Assert.True(File.Exists(resolved), $"Expected runtime corpus asset for {configuredPath} at {resolved}.");
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class RepositoryRootFixture : IDisposable
|
||||
{
|
||||
private RepositoryRootFixture(
|
||||
@@ -131,10 +164,12 @@ public sealed class KnowledgeSearchRepositoryRootResolverTests
|
||||
{
|
||||
var workspaceRoot = Path.Combine(Path.GetTempPath(), "stellaops-knowledge-runtime-" + Guid.NewGuid().ToString("N"));
|
||||
var appBaseDirectory = Path.Combine(workspaceRoot, "app");
|
||||
var snapshotDirectory = Path.Combine(appBaseDirectory, "src", "AdvisoryAI", "StellaOps.AdvisoryAI", "UnifiedSearch", "Snapshots");
|
||||
|
||||
Directory.CreateDirectory(Path.Combine(appBaseDirectory, "docs", "modules", "advisory-ai"));
|
||||
Directory.CreateDirectory(Path.Combine(appBaseDirectory, "devops", "compose"));
|
||||
Directory.CreateDirectory(Path.Combine(appBaseDirectory, "src", "AdvisoryAI", "StellaOps.AdvisoryAI", "KnowledgeSearch"));
|
||||
Directory.CreateDirectory(snapshotDirectory);
|
||||
|
||||
File.WriteAllText(Path.Combine(appBaseDirectory, "docs", "README.md"), "# docs");
|
||||
File.WriteAllText(Path.Combine(appBaseDirectory, "docs", "modules", "advisory-ai", "knowledge-search.md"), "# advisory");
|
||||
@@ -148,6 +183,13 @@ public sealed class KnowledgeSearchRepositoryRootResolverTests
|
||||
File.WriteAllText(
|
||||
Path.Combine(appBaseDirectory, "src", "AdvisoryAI", "StellaOps.AdvisoryAI", "KnowledgeSearch", "doctor-search-controls.json"),
|
||||
"[]");
|
||||
File.WriteAllText(Path.Combine(snapshotDirectory, "findings.snapshot.json"), "[]");
|
||||
File.WriteAllText(Path.Combine(snapshotDirectory, "vex.snapshot.json"), "[]");
|
||||
File.WriteAllText(Path.Combine(snapshotDirectory, "policy.snapshot.json"), "[]");
|
||||
File.WriteAllText(Path.Combine(snapshotDirectory, "graph.snapshot.json"), "[]");
|
||||
File.WriteAllText(Path.Combine(snapshotDirectory, "opsmemory.snapshot.json"), "[]");
|
||||
File.WriteAllText(Path.Combine(snapshotDirectory, "timeline.snapshot.json"), "[]");
|
||||
File.WriteAllText(Path.Combine(snapshotDirectory, "scanner.snapshot.json"), "[]");
|
||||
|
||||
return new RuntimePublishLayoutFixture(workspaceRoot, appBaseDirectory);
|
||||
}
|
||||
|
||||
@@ -299,20 +299,24 @@ public sealed class UnifiedSearchIngestionAdaptersTests
|
||||
try
|
||||
{
|
||||
Directory.SetCurrentDirectory(fixture.ServiceDirectory);
|
||||
var knowledgeOptions = Options.Create(new KnowledgeSearchOptions
|
||||
{
|
||||
RepositoryRoot = fixture.RepositoryRoot
|
||||
});
|
||||
|
||||
var findingsAdapter = new FindingIngestionAdapter(
|
||||
new StubVectorEncoder(),
|
||||
Options.Create(new KnowledgeSearchOptions()),
|
||||
knowledgeOptions,
|
||||
NullLogger<FindingIngestionAdapter>.Instance);
|
||||
var policyAdapter = new PolicySearchAdapter(
|
||||
new StubHttpClientFactory(),
|
||||
new StubVectorEncoder(),
|
||||
Options.Create(new KnowledgeSearchOptions()),
|
||||
knowledgeOptions,
|
||||
NullLogger<PolicySearchAdapter>.Instance);
|
||||
var vexAdapter = new VexSearchAdapter(
|
||||
new StubHttpClientFactory(),
|
||||
new StubVectorEncoder(),
|
||||
Options.Create(new KnowledgeSearchOptions()),
|
||||
knowledgeOptions,
|
||||
NullLogger<VexSearchAdapter>.Instance);
|
||||
|
||||
var findings = await findingsAdapter.ProduceChunksAsync(CancellationToken.None);
|
||||
|
||||
Reference in New Issue
Block a user