import { type DeployPackage } from "../deploy/package.js"; /** One hardcoded ticker-shaped string, with the exact place a reader has to edit. */ export interface TickerOccurrence { ticker: string; /** Absolute path of the file the name appears in — strategy.yaml or an instance runtime.yaml. */ file: string; /** Dotted key path, e.g. `catalog.assets` or `scanners[0].inputs.asset_universe`. */ keyPath: string; } /** Every hardcoded ticker-shaped string in catalog.assets + each instance's scanners[].inputs. */ export declare function packageHardcodedTickers(pkg: DeployPackage): TickerOccurrence[]; /** * Mirror of validate_universe.py `unknown_tickers`: scanners on the xyz DEX prefix bare names in * code (`f"xyz:{token}"`), so a bare ticker is live if `T` OR `xyz:T` is; a prefixed one only as * written. Returns ticker → every occurrence of it, so one refusal can name every place to edit. */ export declare function deadTickers(occurrences: TickerOccurrence[], live: ReadonlySet): Map; /** The injected universe source — deliberately the same shape as `DeployDeps.listLiveInstruments`. */ export interface UniverseCheckDeps { /** Non-delisted live instrument names; [] means "could not read", NEVER "everything is dead". */ listLiveInstruments(): Promise; } export type UniverseCheckResult = /** Nothing hardcoded — derived universe; the source was never read. */ { status: "no-hardcoded"; } | { status: "clean"; liveCount: number; checked: number; } | { status: "dead"; dead: Map; liveCount: number; } /** The list could not be read (throw, or empty). No instrument may be called dead on this. */ | { status: "unavailable"; reason: string; }; /** * The composed, reusable check: performs no I/O beyond the package's own YAML and the injected * source, and returns a verdict any consumer can render. Deploy consumes it pre-money; validate * consumes it read-only at its live depth. * * What it throws, exactly: **the injected source never throws out of here** — a rejecting or empty * `listLiveInstruments` becomes `{ status: "unavailable" }`, which is the whole point of the * status. Reading the package's own YAML is NOT wrapped: an instance `runtime.yaml` that has been * deleted or made unparseable since the package loaded propagates its error. On the deploy path * that cannot happen unobserved — `instancesWithoutDslExit` and `scannersDeclaringEnabled` parse * the same files a few lines earlier in `runDeploy`, and `localStartRefusal` parses them at start — * so the exposure belongs to the standalone consumer, and validate's call site CATCHES it: a * package it could not read is reported as a check that did not run * (`W_VALIDATE_UNIVERSE_UNCHECKED`), never as a clean one. That stayed a caller's concern rather * than becoming a fifth status because it is NOT `unavailable` — "the live list could not be read" * and "this package could not be read" are opposite facts — and deploy, which parses the same files * first, has no branch that would ever reach it. */ export declare function checkPackageUniverse(pkg: DeployPackage, deps: UniverseCheckDeps): Promise; /** * The verdict as one journal line — plain words, never the union's tag name (`dead`/`unavailable` * are internal labels, and a narration line is read by people and relayed by agents). `null` for a * package that hardcodes nothing: there is no forward claim to make about a check that never ran. * Carries no money language, so a read-only consumer can render it too. */ export declare function describeUniverseVerdict(result: UniverseCheckResult): string | null; /** * The live names a hardcoded ticker was compared against — the reader's half of {@link deadTickers}. * * Exported because both renderers state it and neither may re-derive it: deploy's refusal and * validate's finding must name the SAME two forms the comparison actually used, or one of them is * telling an author to look for a name that was never checked. */ export declare function checkedTickerForms(ticker: string): string[]; /** * ONE refusal for the whole package, D-2 shape: every dead name, its literal value, its exact * locations, and the mechanical fix — a reader repairs the whole universe in one pass. Both * re-check routes are named, the runtime one first: the skills tool is what the author-side skill * teaches, and `senpi validate` is what writes the proof deploy refuses a package without — so the * loop "fix → re-check → deploy" never moves money until green, AND can actually close. * * Every "nothing was created" claim here is scoped to THIS RUN, deliberately. The gate fires before * the first read of this package's live state, so on an adopt/resume run the package may already have * a funded wallet and an installed runtime that this refusal cannot see — an absolute "no wallet was * funded" would be false exactly there, and the move it invites (create and fund a second wallet * beside the live one) is the expensive one. The gate may claim what it did, never what exists. Note * the scoping has to stay precise in the other direction too: the gate DID read one live surface (the * instrument list it quotes a count from), so it may not claim it read nothing live. */ export declare function buildUniverseNotLiveRefusal(dead: Map, pkg: DeployPackage, liveCount: number, budget?: number): string; /** * The fail-closed unavailability detail — deliberately CODE-LESS: a code marks a refusal, and * this is a step that could not run. Unknown is never "not live": no instrument is named dead * on a read that did not succeed, so the message must never look like E_UNIVERSE_NOT_LIVE. */ export declare function buildUniverseUnavailableDetail(reason: string, pkg: DeployPackage): string; //# sourceMappingURL=package-universe.d.ts.map