/** * The package-derivable gates `senpi deploy` refuses on, asked at validate's STATIC depth. * * Deploy's pre-money block decides four things from the package's own bytes: an instance with no * DSL exit, a scanner declaring an unsupported `enabled` key, a mixed-case package id, and two * instances sharing one recipe directory. None of them can change between a validation and a * deploy — unlike the universe check, whose TOCTOU justification is spelled out in `proof-gate.ts` * — so validate reporting green on bytes deploy rejects is not a race, it is a divergence. The * author would first learn about a package-derivable fault from the money path, which is what * `senpi validate` exists to prevent (`wallet-binding-stage.ts` made this move first, for the * binding gate; this is the rest of the set). * * Each refusal these mirror also tells its reader to run `openclaw senpi validate` — so without * this module, following a deploy refusal's own instruction returns PASS and disproves the refusal * that emitted it. * * ## Why STATIC depth * * Every check here reads the package's own bytes and nothing else: no exchange, no gateway, no * credentials. That puts them at the shallowest depth, where `depthsUpTo` runs them at every depth * above — so an offline CI run with no MCP server reachable still catches them. None of them halts * the deeper stages (`NON_HALTING_CODES` in `run.ts`): a package that cannot be funded is still a * package whose scanner an author is entitled to import and tick. * * ## Two checks read the config, two read the package * * The DSL-exit and scanner-`enabled` faults live in the recipe, so they are asked of the config * `collectRecipeFindings` has already parsed. That covers a recipe with no manifest around it yet * — the mid-authoring case deploy cannot see at all — and it means neither check can throw on a * recipe that does not parse: `config` is `undefined` there, and the YAML-syntax gate already owns * that fault and words it properly. The id-case and directory-collision faults live in the * manifest, so they need `target.pkg` and are silent without one. * * ## Scoped to the recipe being validated * * `target.ts` resolves a package ROOT to a refusal ("pick an instance"), so every run that reaches * here is about exactly one recipe. Reporting a sibling instance's fault would be telling the * author to edit a file this command did not look at — the rule `wallet-binding-stage.ts` states. * The id-case check is the deliberate exception: the id belongs to the package, so it is this * recipe's problem too, and its fix is one edit in a file the author already has open. * * ## An unreadable manifest is silent here, deliberately * * Same call `wallet-binding-stage.ts` makes, for the same reason. When `target.packageUnreadable` * is set, `target.pkg` is absent and the two package-level checks go quiet — but that is not * failing open: `target.ts` raises `E_VALIDATE_UNREADABLE_MANIFEST` at the package root, the * universe check reports the same unreadable file below it, and no reading of a manifest nobody * can read could clear a package for funding. A third voice on one fault is noise. */ import type { RuntimeConfig } from "../runtime/runtime-schema.js"; import type { ResolvedTarget } from "./target.js"; import type { Finding } from "./types.js"; /** * The checks, as findings. * * `config` is `undefined` when the recipe did not parse or failed the schema; both faults are * already reported by the recipe checks, and every question below would be asked of a shape that * was never established. */ export declare function packageGateFindings(target: ResolvedTarget, config: RuntimeConfig | undefined): Finding[]; //# sourceMappingURL=package-gates-stage.d.ts.map