/** * Workflow discovery (DES-walkthrough-proof §4.13; WT-W4): two deterministic, propose-only queries, * registered as trigger-registry entries and fired on a run's terminal frames. * * added_by_hand per project, a catalog id a PERSON added to N consecutive launched chains (the * steps of `plan.proposed{by:"human"}` the PA's proposal did not have; floor-added * never; PA additions — `pa_added`, `member_request` — never) and never overrode * → a testing-rule draft that makes the step the default for the observed kinds. * what_catches per project per 30 days, a walkthrough FAIL while the same run's `test` verdict * was PASS, K times → hold TST-1002 (Test plus a walkthrough review). * * Both count over ONE project-level view the daemon builds and the registry hands over as * `ctx.discovery` (bounded, cached; `src/api/discovery-source.ts`). The checks stay pure over that * view: no bus read, no ledger read, no engine call here. * * A hit is one `proposal` row per (project, query, draft hash) — RUN-LESS and project-scoped * (`project` on the output; the emitter keys it to the project, so a second run of the project * re-deriving the same draft resolves to the row already there, across restarts too). The emitter * hands the row to the existing review queue (`facts.proposal` = the estate `proposal.submit` item, * `kind_type: "policy:testing"`, payload `{rule, severity, evidence: {count, window, run_ids}}`). * Nothing here lands a rule: approval is the operator's, in the queue (§4.13 "Approving"). The draft * is a proposal, not the operator's words, so it never auto-remembers. * * The draft hash is over the RULE text, not the count: a sixth consecutive run re-derives the same * draft and raises nothing new. A changed set of observed kinds is a new draft. * * A run whose records could not be read stays in the view as `unknown` (nothing added, no verdicts): * it breaks a streak it sits inside and never counts as a hit — unknown is never "yes". */ import type { DiscoverySnapshot, WatchCheck } from '../types.js'; export type DiscoveryQuery = 'added_by_hand' | 'what_catches'; export interface AddedByHandParams { /** The catalog ids a testing rule may oblige — only a step of this kind becomes a proposal. */ catalog: string[]; } export interface AddedByHandThreshold { /** Consecutive launched chains the step must have been added to, counted from the newest back. */ consecutive: number; } export interface WhatCatchesThreshold { times: number; window_days: number; } export interface DiscoveryProposal { query: DiscoveryQuery; /** `added_by_hand`: the step. */ catalog?: string; /** The rule statement the proposal carries (the operator's review queue shows it verbatim). */ rule: string; /** The watch row's sentence (the Watchtower's question). */ sentence: string; evidence: { count: number; window: string; run_ids: string[]; kinds: string[]; }; } /** The dedupe key's draft part: 12 hex of sha256 over (query, rule). */ export declare function draftHash(query: DiscoveryQuery, rule: string): string; export declare function addedByHandProposals(snap: DiscoverySnapshot, params: AddedByHandParams, threshold: AddedByHandThreshold): DiscoveryProposal[]; export declare function whatCatchesProposals(snap: DiscoverySnapshot, threshold: WhatCatchesThreshold, now: number): DiscoveryProposal[]; export declare const addedByHandCheck: WatchCheck; export declare const whatCatchesCheck: WatchCheck, WhatCatchesThreshold>; //# sourceMappingURL=discovery.d.ts.map