@fanalis/orchestrator
v0.1.0
Published
Audit orchestrator — runs all pillars against a rendered context, computes the genre-aware composite, returns the report.
Readme
@fanalis/orchestrator
per-route audit driver. takes a url + a list of pillar adapters + options; returns a single AuditReport.
entry
runAudit(url, pillars, {
tier, // 1..5
noDownloads, // refuse to fetch new models
siteType, // override the auto-detected genre ("saas" / "ecommerce" / etc)
log, // (msg) => void
models, // ModelLoader (defaults to createLoader())
llm, // LLMRunner | null
visionLLM, // VisionLLMRunner | null (post-v1)
auditId, // pin a stable id (the CLI does this so reports replay)
keepBrowser, // don't closeBrowser() at end (for batch mode)
}) → AuditReportwhat one call does
- detect hardware → pick budget per tier (
TIER_BUDGETS[tier].budgetSec) renderUrl(url)→AuditContext(from@fanalis/render)- site-type classification (saas / ecommerce / docs / etc) for composite genre-weighting, unless caller overrides
Promise.allSettledoverpillars, each wrapped inwithTimeout(p.runAtTier(ctx, opts), budget * 1000, p.id). failures yield a neutral 50-score finding with the error message — never a missing pillarcomputeComposite(pillarScores, siteType)from@fanalis/core— power-mean with genre weights- signature = sha256 of
{engineVersion, tier, siteType, weights, pillarIds.sort()}truncated to 16 chars. lets the same report fingerprint identify identical engine configs across runs. - unless
keepBrowser,closeBrowser()from@fanalis/render
what's NOT here
- source-pass modules (those run from the CLI directly via
@fanalis/repo; the orchestrator only drives the render-pass pillars) - saved-report persistence (the CLI uses
@fanalis/models/reportsfor that) - llm narrative end-of-audit summary (the CLI does that — orchestrator just forwards the
llmrunner into pillars)
caveats
runAtTieris per-pillar's responsibility. timeout is enforced from the outside; long-running pillars get killed and yield the neutral fallback.- the orchestrator is stateless across calls. concurrency comes from the CLI parallel-route batch (
--concurrency N→Promise.all(batch.map(runAudit))). lighthouse runs inside the perf pillar are mutex-serialised viawithLighthouseLockin@fanalis/pillar-performance/lighthouse.ts— they can't all spawn chrome simultaneously even with high route concurrency. audit.lighthouseis filled by the perf pillar insiderunAtTier, not by the orchestrator. the rest of the pillars see it viactx.lighthouseonly if it ran before them — which is why perf is typically registered early in the pillar array.
