/** * Warn-only adoption advisory for the OPTIONAL `dsh-llm-fallbacks` plugin * (plan Task 4 + when the capability is mounted, ONE advisory pass per apply * reports the deployment's fallbacks taxonomy state (bounded: ≤1 warn per * category, logger `mstar/fallbacks-advisory`): * * - Service present (seeds-aware path): the decision point FIRST awaits the * idempotent re-declare (`declareMstarSeeds`) — converging the boot * dual-inject-child race window — then reads the EFFECTIVE state * (`getEffectiveRoles`, sync) and reports per mstar role id: * (i) missing row → missing warn; (ii) `seeded && !personaOverridden` → * seeded (silent, one debug); (iii) `personaOverridden` → persona- * overridden warn (ids + the revert entry: the `fallbacks/revert-seed` * gateway / settings-card rollback button). Empty-persona warns fire only * for non-seeded rows or overridden-empty rows. The declare outcome's * skips/conflicts (upstream conflict code `'persona-source'`) merge into * one warn. The legacy-keys check runs through the service's own * `detectLegacyKeys` on the row config. * - Loader-fallback path (no service): the structural read is preserved * (`readRowConfig`/`readRolesList` — (b) missing ids / (c) empty personas * over the raw `roles.list`); the legacy check is SKIPPED (never * reimplemented) and no revert entry appears (no seeds surface). * * The mstar role-id set is derived from the `harness-agents/` mirror * (`subagentRoleIds` — shell file stems filtered to `mode: subagent`), * never hardcoded. * * Unreadable row config (absent field / non-object, or an unreadable * `roles.list`) → skip + one debug log. Unmounted → the pass is not invoked * (`{ ran: false, converged: false }`, no logs). An aborted pass (any caught * error, including a rejected re-declare) reports `{ ran: true, converged: * false }` — the honest latch: the caller arms its one-shot latch only on * `ran && converged`, so a failed pass never suppresses the decision-point * retry. The degraded-abort warn is deduplicated to at most ONE per apply * (module flag; the entry resets it via {@link resetAdvisoryAbortWarn}). * The advisory NEVER writes the fallbacks config — the read is read-only * over the deployment's config layer (never the fallbacks plugin's module * internals); the only write path is the idempotent seeds re-declare * through the released seeds surface (no-delta → no settings write * upstream). The advisory never throws (the caller's dispatch/apply flow is * never affected). * * Module boundary: no barrel — the entry imports this module by explicit * relative path (the role-persona module pattern). */ import type { Context } from '@deepseek-ai/cordis'; /** Logger label for the adoption advisory (dsh logger naming: `/`). */ export declare const ADVISORY_LOGGER = "mstar/fallbacks-advisory"; /** Advisory log levels the module sink understands. */ export type AdvisoryLogLevel = 'debug' | 'warn'; /** Module-level advisory log sink — bound by `apply` to `ctx.logger(ADVISORY_LOGGER)` (role-persona module pattern). */ export type AdvisoryLogSink = (level: AdvisoryLogLevel, message: string) => void; /** * Bind the advisory log sink (the entry `apply` binds it to * `ctx.logger(ADVISORY_LOGGER)`). Returns the PRIOR sink so a caller can * restore it (test pattern: {@link setDecorationLogger}). */ export declare function setAdvisoryLogger(sink: AdvisoryLogSink): AdvisoryLogSink; /** * Warn id-list cap: an id-list warn line lists at most this many ids before * the `… and K more` suffix — a huge registry (thousands of rows) must not * produce a multi-KB log line (cap). Exported for the * suite's cap assertions; module surface only — the entry's frozen 47-name * export surface deliberately does not re-export it. */ export declare const ADVISORY_ID_LIST_CAP = 20; /** * One advisory pass outcome (the honest-latch contract): * - `ran` — the pass executed (the capability is mounted); `false` means the * pass was not invoked (unmounted). Carries the one-pass-per-apply * bookkeeping. * - `converged` — the pass reached its converged end. Per return path: * unmounted → `false`; aborted pass (any caught error, including a * rejected re-declare) → `false`; a no-re-declare path (loader-fallback * structural read, unreadable config, or a service-present pass that * never reaches the re-declare) → `true`; service-present path → reflects * the re-declare resolving. * * The caller (entry `apply`) arms its one-shot latch only on * `ran && converged` — a rejected re-declare must never suppress the * `subagent/start` decision-point retry. */ export interface AdvisoryPassReport { ran: boolean; converged: boolean; } /** * Reset the degraded-abort warn dedup flag (one warn per apply budget). * Called by the entry at `apply` (next to the advisory sink binding) and in * the `llm-fallbacks` inject child's teardown (a fiber swap re-opens the * budget for the re-applied fiber). Exported for the suite's dedup case. */ export declare function resetAdvisoryAbortWarn(): void; /** * One advisory pass: unmounted → not invoked (`{ ran: false, converged: * false }`, no logs); mounted → report the taxonomy adoption state (bounded: * ≤1 warn per category). With the service present the pass is ASYNC: it * awaits the idempotent re-declare before the effective-state readback * (report determinism — the boot dual-inject-child race window is closed). * Never throws — every failure mode degrades to skip + one debug/warn, and * an aborted pass reports `converged: false` (the honest latch). Never * writes the fallbacks config. * * @param ctx - the plugin's registrant context (the app composition root). * @param agentsDir - the `harness-agents/` mirror root the mstar role-id set * is derived from; absent → the taxonomy checks are skipped (one debug * log; the legacy-keys check is mirror-independent and still runs). * @returns the {@link AdvisoryPassReport} — `ran` marks a mounted pass (the * one-pass-per-apply bookkeeping), `converged` marks a pass that reached * its converged end; the caller (entry `apply`) arms the one-shot latch * only on `ran && converged`, so an aborted pass (e.g. a rejected * re-declare) never suppresses the decision-point retry. */ export declare function runFallbacksAdvisory(ctx: Context, agentsDir: string | undefined): Promise;