@harness-engineering/intelligence 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _harness_engineering_types from '@harness-engineering/types';
2
- import { Issue, ConcernSignal, ScopeTier, EscalationConfig, ComplexityLevel, ComplexityVerdict, CapabilityTier, RoutingRisk, RoutingPolicy } from '@harness-engineering/types';
2
+ import { Issue, ConcernSignal, ScopeTier, EscalationConfig, ComplexityLevel, ComplexityVerdict, CapabilityTier, RoutingRisk, RoutingPolicy, RoutingTaskText } from '@harness-engineering/types';
3
3
  import { z } from 'zod';
4
4
  import { GraphStore } from '@harness-engineering/graph';
5
5
 
@@ -1491,4 +1491,623 @@ declare function deriveRequiredTier(complexity: ComplexityVerdict, risk: Routing
1491
1491
  /** Flatten signals into the ComplexityVerdict.signals map, dropping undefined fields. */
1492
1492
  declare function serializeSignals(s: ComplexitySignals): Record<string, number | boolean | string>;
1493
1493
 
1494
- export { ACCEPTANCE_EVAL_SYSTEM_PROMPT, type AcceptanceEvalInput, AcceptanceEvaluator, type AcceptanceEvaluatorOptions, type AcceptanceVerdict, type AffectedSystem, type AnalysisProvider, type AnalysisRequest, type AnalysisResponse, AnthropicAnalysisProvider, type Authority, type BlastRadius, type BlindSpot, type CanaryAdapter, type CanaryDegradeReason, type CanaryExec, type CanaryFinding, type CanaryProbe, type ClassifyInput, ClaudeCliAnalysisProvider, type ComplexityScore, type ComplexitySignals, type Confidence, DEFAULT_DEGRADE_AT_PCT, type EnrichedSpec, type ExecutionOutcome, ExecutionOutcomeConnector, type ExpertiseLevel, type Finding, type FrameworkRecommendation, type GitHubIssue, GraphValidator, IntelligencePipeline, type JiraIssue, type JudgedAgainst, type LinearIssue, type LlmAcceptanceVerdict, type LlmVerdict, type ManualInput, type Measurability, OUTCOME_EVAL_SYSTEM_PROMPT, OpenAICompatibleAnalysisProvider, type OutcomeEvalInput, OutcomeEvaluator, type OutcomeEvaluatorOptions, type OutcomeIngestResult, type OutcomeVerdict, type PersonaEffectivenessScore, type PersonaRecommendation, PeslSimulator, type Phase, type PreprocessResult, type ProfileStore, RANK_TIER, type RawWorkItem, type ResolvedSection, SENSITIVE_BLAST_THRESHOLD, STATIC_WEIGHTS, type SimulationResult, type SpecializationEntry, type SpecializationProfile, type SpecializationScore, type StaticVerdict, TIER_RANK, type TaskType, type TemporalConfig, type TiebreakResult, type Verdict, type WeightedRecommendation, acceptanceVerdictSchema, applyBudgetClamp, baseTier, blastRadiusVeto, buildUserPrompt as buildAcceptanceUserPrompt, buildSpecializationProfile, buildUserPrompt$1 as buildUserPrompt, classify, computeExpertiseLevel, computeHistoricalComplexity, computePersonaEffectiveness, computeSemanticComplexity, computeSpecialization, computeStructuralComplexity, createCanaryAdapter, decayWeight, deriveAcceptanceAuthority, deriveAuthority, deriveRequiredTier, detectBlindSpots, enrich, findingSchema, githubToRawWorkItem, jiraToRawWorkItem, linearToRawWorkItem, llmTiebreak, loadProfiles, manualToRawWorkItem, recommendPersona, refreshProfiles, resolveSection, runGraphOnlyChecks, runLlmSimulation, runStaticPass, saveProfiles, score as scoreCML, scoreToConcernSignals, serializeSignals, temporalSuccessRate, toRawWorkItem, verdictSchema, weightedRecommendPersona };
1494
+ /**
1495
+ * Escalation category for a triaged item — the reason a non-dispatched item was
1496
+ * held (SC-F2's closed set) or the routing bucket a dispatched item fell into.
1497
+ * Part of the `shapeKey` so precedent base-rates aggregate like-for-like work.
1498
+ */
1499
+ type EscalationCategory = 'not-in-band' | 'unresolved-scope' | 'scope-too-large' | 'open-decision' | 'halted-fork' | 'precedent-contradicts' | 'error' | 'dispatchable';
1500
+ /** Autonomy-ratchet stage in effect at dispatch (D14). 1 = human before execution. */
1501
+ type RatchetStage = 1 | 2 | 3 | 4;
1502
+ /**
1503
+ * The pre-diff prediction, written by Phase 3 at dispatch. It is the confidence-capped
1504
+ * (S3-001) claim the post-diff retrospective later grades against ground truth.
1505
+ */
1506
+ interface TriagePrediction {
1507
+ /** The pre-diff prediction being made (level + confidence-capped verdict). */
1508
+ verdict: ComplexityVerdict;
1509
+ /**
1510
+ * An OPAQUE DIAGNOSTIC SNAPSHOT of the probe's signals at dispatch (today: the
1511
+ * verdict's static `signals` map) — kept for human forensics, NOT a grading input.
1512
+ * It is deliberately NOT the typed Phase-1 `ProbeLevers`: the Phase-4 retrospective
1513
+ * comparator grades on `verdict.level` + `scopeEstimate` ONLY (see
1514
+ * `retrospective.ts`) and never reads this field, so its shape can vary without
1515
+ * affecting the grade. Threading the full typed `ProbeLevers` end-to-end was
1516
+ * rejected as unneeded coupling (the marker's `ReadyCandidate` has no consumer for
1517
+ * it). If a future lever genuinely needs to inform grading, promote it to a typed
1518
+ * field here rather than smuggling it through this untyped bag.
1519
+ */
1520
+ levers: Record<string, unknown>;
1521
+ /** Predicted blast radius (estimated post-diff scope from the scope lever). */
1522
+ scopeEstimate: number;
1523
+ /** Ratchet stage in effect when this item was dispatched. */
1524
+ ratchetStage: RatchetStage;
1525
+ }
1526
+ /**
1527
+ * The post-diff outcome, written by Phase 4 at the retrospective. This is the only
1528
+ * gate that sees ground truth; its verdict is what feeds the precedent lever (D13).
1529
+ */
1530
+ interface TriageOutcome {
1531
+ /** Full-strength post-diff verdict on the ACTUAL diff (confidence may reach high). */
1532
+ actual: ComplexityVerdict;
1533
+ /** 0 = matched the prediction; >0 = mispredict magnitude (over-scope). */
1534
+ exceededBy: number;
1535
+ /** True when the actual diff stayed within the predicted band. */
1536
+ matched: boolean;
1537
+ }
1538
+ /**
1539
+ * The accreting triage record for one roadmap item. `prediction`/`outcome` are
1540
+ * absent until the owning phase writes its slice; a record with a populated
1541
+ * `outcome` is a graded, precedent-eligible record.
1542
+ */
1543
+ interface TriageRecord {
1544
+ /** Stable item key (roadmap `External-ID`). */
1545
+ externalId: string;
1546
+ /** Bucketing key for precedent/ratchet aggregation (see {@link shapeKey}). */
1547
+ shapeKey: string;
1548
+ /** Written by Phase 3 at dispatch. */
1549
+ prediction?: TriagePrediction;
1550
+ /** Written by Phase 4 at the retrospective. */
1551
+ outcome?: TriageOutcome;
1552
+ /** ISO timestamp stamped by the writer (not by shapeKey). */
1553
+ ts: string;
1554
+ }
1555
+ /**
1556
+ * The precedent lever (P1 injects this; P4 implements the real one). A pure read over
1557
+ * records sharing a `shapeKey` with a populated `outcome`: success rate = matched / total.
1558
+ * Absent history ⇒ `unknown` (the P1 degrade-empty path), which is simply "no records
1559
+ * for this shape yet" — never a block on emptiness.
1560
+ */
1561
+ interface PrecedentLookup {
1562
+ /**
1563
+ * Measured autonomous-success rate for the given shape, or `unknown` when no
1564
+ * outcome-bearing records exist for it (cold-start).
1565
+ */
1566
+ rateForShape(shapeKey: string): PrecedentRate;
1567
+ }
1568
+ /**
1569
+ * The precedent lever's result: a measured base-rate over recorded outcomes, or
1570
+ * `unknown` on cold-start (no outcome-bearing records for the shape yet).
1571
+ */
1572
+ type PrecedentRate = {
1573
+ readonly kind: 'unknown';
1574
+ } | {
1575
+ readonly kind: 'rate';
1576
+ readonly matched: number;
1577
+ readonly total: number;
1578
+ readonly rate: number;
1579
+ };
1580
+ /**
1581
+ * The bucketing key for precedent/ratchet aggregation:
1582
+ * `sortedLabels + '|' + escalationCategory + '|' + predictedLevel`.
1583
+ *
1584
+ * Deterministic and label-order-independent: labels are de-duplicated, trimmed of
1585
+ * empties, and sorted before joining, so `['a','b']` and `['b','a']` (and
1586
+ * `['b','a','a']`) all bucket identically. This is the quiet linchpin — too coarse
1587
+ * lumps unlike work (unsafe base-rates), too fine leaves every item its own bucket
1588
+ * (precedent perpetually `unknown`). Phase 4 calibration revisits this granularity
1589
+ * first; the definition lives here so P1 and P4 never disagree.
1590
+ */
1591
+ declare function shapeKey(labels: readonly string[], category: EscalationCategory, level: ComplexityLevel): string;
1592
+ /**
1593
+ * The `dispatchable`-bucket shapeKey — the ONE convention prediction and outcome must agree on.
1594
+ *
1595
+ * A dispatched/approved item is (by definition) dispatchable, so its precedent/ratchet bucket is
1596
+ * `shapeKey(labels, 'dispatchable', level)`. That spelling was previously re-typed at three sites
1597
+ * (the probe's precedent lookup, the CLI approve gate, the orchestrator marker); if any drifted —
1598
+ * or keyed off a different `level` source — the PREDICTION and the OUTCOME would bucket into
1599
+ * DIFFERENT shapes and silently break precedent aggregation. Centralizing it here makes that
1600
+ * divergence impossible: all three call this with the SAME level (the probe's `verdict.level`).
1601
+ */
1602
+ declare function dispatchableShapeKey(labels: readonly string[], level: ComplexityLevel): string;
1603
+
1604
+ /**
1605
+ * Base-rate for a single shape over the supplied records. Counts only outcome-bearing
1606
+ * records matching `shapeKey`; returns `unknown` when there are none (cold-start).
1607
+ */
1608
+ declare function aggregatePrecedent(records: readonly TriageRecord[], shapeKey: string): PrecedentRate;
1609
+ /**
1610
+ * Build a {@link PrecedentLookup} backed by a fixed record set — the real precedent
1611
+ * lever Phase 4 injects once outcomes exist. With no outcome-bearing records for a
1612
+ * shape it returns `unknown`, so an empty set yields the Phase-1 cold-start behavior
1613
+ * for every shape.
1614
+ */
1615
+ declare function precedentLookupFromRecords(records: readonly TriageRecord[]): PrecedentLookup;
1616
+
1617
+ /**
1618
+ * Extract candidate entity mentions (symbol/path names) from roadmap-row text.
1619
+ *
1620
+ * Pure and deterministic: returns de-duplicated candidates in first-seen order across
1621
+ * the four strategies. Returns an EMPTY array when the text carries none of the
1622
+ * structured shapes — the explicit "no entities found" signal P1 relies on (it becomes
1623
+ * `unresolved-scope`, never a fallback). Non-string / empty input ⇒ `[]`.
1624
+ */
1625
+ declare function extractEntities(text: string): string[];
1626
+
1627
+ /**
1628
+ * One lever's result. Every lever either produces a concrete value or degrades to the
1629
+ * literal `'unknown'` (never throwing out of the probe), carrying an optional `reason`
1630
+ * that feeds the verdict's `rationale`. A degraded lever LOWERS corroboration; it never
1631
+ * forces a pass (proposal §"any lever that returns 'unknown' lowers the corroboration
1632
+ * score rather than forcing a pass").
1633
+ */
1634
+ interface LeverResult<T> {
1635
+ /** The lever's value, or the literal `'unknown'` when it could not be determined. */
1636
+ value: T | 'unknown';
1637
+ /** Human-legible note (why it degraded, or a one-line summary of the finding). */
1638
+ reason?: string;
1639
+ }
1640
+ /** A single resolved-entity scope datum from the graph seam. */
1641
+ interface ResolvedEntity {
1642
+ /** The raw candidate that resolved (as emitted by extractEntities). */
1643
+ candidate: string;
1644
+ /** The graph node id it resolved to. */
1645
+ nodeId: string;
1646
+ /** Estimated blast radius (affected-node count) from the graph for this entity. */
1647
+ blastRadius: number;
1648
+ }
1649
+ /**
1650
+ * The scope lever's value: the graph-grounded scope estimate. `resolved` is the subset
1651
+ * of candidates that ACTUALLY resolved in the graph — extractEntities over-generates
1652
+ * (it emits `e.g`/`i.e` noise and other non-symbols), so a non-empty extraction is NOT
1653
+ * itself "scope resolved" (follow-up S3). Only resolved candidates count. When `resolved`
1654
+ * is empty the scope is unresolved and the item is not dispatchable (`unresolved-scope`).
1655
+ */
1656
+ interface ScopeEstimate {
1657
+ /** Candidates emitted by the extractor (pre-resolution). */
1658
+ candidates: readonly string[];
1659
+ /** The subset that resolved against the graph (empty ⇒ unresolved scope). */
1660
+ resolved: readonly ResolvedEntity[];
1661
+ /** Aggregate estimated blast radius across resolved entities (max, the worst case). */
1662
+ blastRadius: number;
1663
+ /** Distinct architectural layers the resolved entities touch (feeds ComplexitySignals). */
1664
+ layersTouched: number;
1665
+ /** Count of resolved entities (proxy for filesTouched into the static pass). */
1666
+ filesTouched: number;
1667
+ }
1668
+ /**
1669
+ * The injected graph-resolution seam. The pure probe NEVER touches a GraphStore — it is
1670
+ * handed this. It maps a candidate entity string to a resolved node + blast radius, or
1671
+ * `null` when the candidate does not resolve (vague/non-symbol candidate). The wiring
1672
+ * layer (orchestrator/CLI) implements it over GraphStore + CascadeSimulator; tests stub
1673
+ * it. This is the S3 seam: raw-string resolution is NOT cleanly exposed by the graph
1674
+ * package, so it lives behind this injected boundary rather than inside the probe.
1675
+ */
1676
+ interface GraphScope {
1677
+ /**
1678
+ * Resolve a candidate entity mention to a graph node + blast radius, or `null` if it
1679
+ * does not resolve. May be sync or async; the probe awaits it. MUST NOT throw — but
1680
+ * the probe still guards it (any throw degrades the scope lever to `unknown`).
1681
+ */
1682
+ resolve(candidate: string): ResolvedEntity | null | Promise<ResolvedEntity | null>;
1683
+ }
1684
+ /**
1685
+ * The open-decisions self-assessment the semantic-read lever surfaces: the human/agent
1686
+ * boundary. Any open decision requiring human judgment (API shape, product tradeoff,
1687
+ * irreversible/outward action) → not dispatchable, regardless of complexity band.
1688
+ */
1689
+ interface OpenDecision {
1690
+ /** Short description of the choice requiring human judgment. */
1691
+ question: string;
1692
+ }
1693
+ /** The closed set of reasons a non-dispatchable item was held (mirrors EscalationCategory). */
1694
+ type HoldReason$1 = 'not-in-band' | 'unresolved-scope' | 'scope-too-large' | 'open-decision' | 'read-incomplete' | 'precedent-contradicts' | 'error';
1695
+ /**
1696
+ * Input to the pure probe for one roadmap item. Built from an `Issue` in the wiring
1697
+ * layer (reusing `buildTaskText`) — the probe stays orchestrator-free and unit-testable.
1698
+ */
1699
+ interface ProbeInput {
1700
+ /** Stable item identity (roadmap External-ID). Absent ⇒ not dispatch-eligible. */
1701
+ externalId: string;
1702
+ /** Pre-diff text-only signals (title+description length, spec/acceptance hints, prompt). */
1703
+ taskText: RoutingTaskText;
1704
+ /** Candidate entity mentions from the item text (from `extractEntities`) — pre-resolution. */
1705
+ entityCandidates: readonly string[];
1706
+ /** Item labels (for shapeKey bucketing / precedent lookup). */
1707
+ labels: readonly string[];
1708
+ /** Whether the item's risk band is high (drives the classifier's standard-tier tie-break). */
1709
+ riskHigh?: boolean;
1710
+ }
1711
+ /** The per-lever bundle carried on every verdict (SC-O1 traceability). */
1712
+ interface ProbeLevers {
1713
+ /** Scope lever: graph-grounded scope estimate (or `unknown` on degrade). */
1714
+ scope: LeverResult<ScopeEstimate>;
1715
+ /** Semantic-read lever: the local-model complexity read (or `unknown`). */
1716
+ semanticRead: LeverResult<ComplexityVerdict>;
1717
+ /** Open-decisions lever: surfaced human-judgment choices (or `unknown`). */
1718
+ openDecisions: LeverResult<readonly OpenDecision[]>;
1719
+ /** Precedent lever: measured base-rate for this shape (or `unknown` at cold-start). */
1720
+ precedent: LeverResult<PrecedentRate>;
1721
+ }
1722
+ /**
1723
+ * The probe's output for one item. `dispatchable` is TRUE only when scope is bounded AND
1724
+ * the semantic read agrees trivial|simple (the eligible band) AND confidence ≥ medium AND
1725
+ * there are no open decisions AND precedent does not contradict. Any shortfall or lever
1726
+ * error fails safe to `dispatchable:false` with a legible `holdReason` + `rationale`.
1727
+ */
1728
+ interface TriageVerdict {
1729
+ /** The item this verdict is for. */
1730
+ externalId: string;
1731
+ /** The corroborated complexity verdict (from the semantic read, or a conservative degrade). */
1732
+ verdict: ComplexityVerdict;
1733
+ /** Authorization decision: only true when all levers corroborate (see the gate above). */
1734
+ dispatchable: boolean;
1735
+ /** The single legible reason it was held (absent when `dispatchable`). SC-F2 closed set. */
1736
+ holdReason?: HoldReason$1;
1737
+ /** All four levers' results (SC-O1 traceability). */
1738
+ levers: ProbeLevers;
1739
+ /** Human-legible corroboration narrative (per-lever notes joined). */
1740
+ rationale: string;
1741
+ }
1742
+
1743
+ /** Tunable gate seeds (a subset of the Phase-0 `roadmap.autoTriage.thresholds`). */
1744
+ interface ProbeConfig {
1745
+ /** Blast-radius ceiling for a "bounded" scope (seed). */
1746
+ boundedScopeMax: number;
1747
+ /** Minimum semantic-read confidence to clear the gate (the S3-001 pre-diff bar). */
1748
+ dispatchConfidence: 'low' | 'medium' | 'high';
1749
+ /**
1750
+ * Precedent block bar: a MEASURED rate at-or-below this contradicts and holds the item.
1751
+ * Default 0 — only a shape that has NEVER succeeded autonomously blocks; `unknown`
1752
+ * (cold-start) never blocks. Conservative-by-construction (proposal §precedent lever).
1753
+ */
1754
+ precedentBlockRate?: number;
1755
+ /** Minimum recorded sample before a precedent rate is trusted to block (seed). Default 1. */
1756
+ precedentMinSample?: number;
1757
+ }
1758
+ /** Injected dependencies for the pure probe. All optional — absent ⇒ that lever degrades. */
1759
+ interface ProbeDeps {
1760
+ /** The SEL analysis provider for the semantic-read + open-decisions levers. Absent ⇒ offline. */
1761
+ provider?: AnalysisProvider;
1762
+ /** The graph-resolution seam for the scope lever. Absent ⇒ scope degrades to unknown. */
1763
+ graph?: GraphScope;
1764
+ /** The precedent lever. Absent ⇒ `unknown` (cold-start), which never blocks. */
1765
+ precedent?: PrecedentLookup;
1766
+ /** Gate seeds. Absent fields fall back to conservative defaults. */
1767
+ config?: Partial<ProbeConfig>;
1768
+ /** Optional model overrides threaded to the classifier tie-break. */
1769
+ models?: {
1770
+ fast?: string;
1771
+ standard?: string;
1772
+ };
1773
+ }
1774
+ /**
1775
+ * Run the pure four-lever scoping probe for one roadmap item. Never throws.
1776
+ */
1777
+ declare function runScopingProbe(input: ProbeInput, deps?: ProbeDeps): Promise<TriageVerdict>;
1778
+
1779
+ /** A candidate to rank: its identity plus the three pilot-score inputs. */
1780
+ interface RankableCandidate {
1781
+ /** Stable item identity (roadmap External-ID) — the final deterministic tiebreak. */
1782
+ externalId: string;
1783
+ /** Business impact (higher = more valuable). Also the secondary sort key (D4). */
1784
+ impact: number;
1785
+ /** Confidence in the estimate (higher = surer). */
1786
+ confidence: number;
1787
+ /** Estimated effort (higher = costlier). Guarded against divide-by-zero. */
1788
+ effort: number;
1789
+ }
1790
+ /**
1791
+ * The roadmap-pilot score: `(impact × confidence) ÷ effort`. Total — an effort of 0 (or
1792
+ * negative) is clamped to a small positive so the score is finite rather than Infinity/NaN,
1793
+ * keeping the sort deterministic.
1794
+ */
1795
+ declare function pilotScore(c: Pick<RankableCandidate, 'impact' | 'confidence' | 'effort'>): number;
1796
+ /**
1797
+ * Rank candidates by pilot score descending, breaking ties by IMPACT descending (SC7),
1798
+ * then by `externalId` ascending for a fully deterministic total order. Pure: returns a
1799
+ * new array; the input is never mutated.
1800
+ */
1801
+ declare function rankTriageCandidates<T extends RankableCandidate>(candidates: readonly T[]): T[];
1802
+
1803
+ /** Self-assessed confidence in a fork recommendation. Mirrors the AMR tie-break enum. */
1804
+ type ForkConfidence = 'high' | 'medium' | 'low';
1805
+ /**
1806
+ * One decision fork the brainstorm surfaces: a design choice with mutually-exclusive
1807
+ * options. The runner asks the generator to recommend a default for each; a fork it can't
1808
+ * confidently recommend is the no-go trigger (SC2). `id` orders forks deterministically.
1809
+ */
1810
+ interface Fork {
1811
+ /** Stable fork identity within a brainstorm (e.g. 'storage-backend'). Orders the loop. */
1812
+ id: string;
1813
+ /** The question this fork decides (human-legible; carried into a halt handoff). */
1814
+ question: string;
1815
+ /** The mutually-exclusive options considered (at least one; usually 2–3). */
1816
+ options: readonly string[];
1817
+ }
1818
+ /**
1819
+ * The generator's decision on a single fork: which option it recommends, how confident it
1820
+ * is (AFTER any self-consistency downgrade), and why. Mirrors `tiebreak.ts` structured
1821
+ * output `{ recommendation, confidence, rationale }` — the schema the SEL provider fills.
1822
+ */
1823
+ interface ForkDecision {
1824
+ /** The fork this decision answers. */
1825
+ fork: Fork;
1826
+ /** The recommended option (should be one of `fork.options`). */
1827
+ recommendation: string;
1828
+ /**
1829
+ * Self-assessed confidence — the gate input. `high` is the ONLY value that auto-accepts;
1830
+ * `medium`/`low` halt (SC2). The generator MUST force this to `low` when self-consistency
1831
+ * sampling shows the recommendation flipped across samples (overconfidence hardening).
1832
+ */
1833
+ confidence: ForkConfidence;
1834
+ /** Why this option, in one or two sentences (carried into the spec draft / halt handoff). */
1835
+ rationale: string;
1836
+ }
1837
+ /**
1838
+ * The injected seam that generates + decides one fork at a time. The pure runner calls this
1839
+ * `depth.maxForks` times (or until it returns `null`, signalling "no more forks — done").
1840
+ *
1841
+ * `index` is the 0-based position in the brainstorm (the runner tracks depth). Returning
1842
+ * `null` means the brainstorm has enumerated every fork it needs — the runner then COMPLETES.
1843
+ * A thrown error is caught by the runner and mapped to `halted{ reason: 'error' }` (SC5):
1844
+ * the generator is allowed to throw; the runner is total.
1845
+ *
1846
+ * Overconfidence hardening (self-consistency) is the GENERATOR's contract: it samples the
1847
+ * underlying model N times per fork and, if the recommendation flips, returns the decision
1848
+ * with `confidence: 'low'`. Keeping it in the generator (behind this seam) makes it testable
1849
+ * with a stub that reports a flip → the pure runner still just reads the enum and halts.
1850
+ */
1851
+ interface ForkGenerator {
1852
+ /**
1853
+ * Produce the next fork's decision, or `null` when there are no more forks. May be async.
1854
+ * MAY throw — the runner catches it and halts with `reason: 'error'`.
1855
+ */
1856
+ next(index: number, priorDecisions: readonly ForkDecision[]): ForkDecision | null | Promise<ForkDecision | null>;
1857
+ }
1858
+ /**
1859
+ * The depth budget: how many forks the brainstorm may explore, scaled by the Phase-1
1860
+ * complexity estimate (SC3). A `trivial` item runs a shallow pass; `simple` a fuller one.
1861
+ * Bounded so a typo never gets the full 4-phase treatment. The runner NEVER exceeds
1862
+ * `maxForks` — if the generator keeps producing forks past the budget, the loop stops and
1863
+ * completes with what it has (the budget is a ceiling, not a required count).
1864
+ */
1865
+ interface DepthBudget {
1866
+ /** Hard ceiling on forks explored. Bounded (e.g. trivial→2, simple→4). Always ≥ 1. */
1867
+ maxForks: number;
1868
+ }
1869
+ /** Map a Phase-1 complexity level to a bounded brainstorm depth (SC3). */
1870
+ declare const DEPTH_BY_LEVEL: Record<ComplexityLevel, DepthBudget>;
1871
+ /** Resolve the bounded depth budget for a complexity level (SC3 depth-scaling). */
1872
+ declare function depthForLevel(level: ComplexityLevel): DepthBudget;
1873
+ /**
1874
+ * A proposal-shaped spec draft accumulated from the accepted fork decisions on clean
1875
+ * completion. Intentionally lightweight (the wiring layer renders it to a proposal.md);
1876
+ * the pure core only accumulates the resolved decisions + a title/summary.
1877
+ */
1878
+ interface SpecDraft {
1879
+ /** The item this spec is for (roadmap External-ID / identifier). */
1880
+ externalId: string;
1881
+ /** A short title (from the item). */
1882
+ title: string;
1883
+ /** One-line summary of the item. */
1884
+ summary: string;
1885
+ /** Every fork the brainstorm resolved, in order — the spec's decision record. */
1886
+ decisions: readonly ForkDecision[];
1887
+ }
1888
+ /**
1889
+ * The input to one brainstorm run: the item identity + text the generator reasons over,
1890
+ * plus the Phase-1 complexity level that scales the depth. Pure — no provider, no IO.
1891
+ */
1892
+ interface BrainstormInput {
1893
+ /** Stable item identity (roadmap External-ID / identifier). */
1894
+ externalId: string;
1895
+ /** Short title (carried into the spec draft). */
1896
+ title: string;
1897
+ /** One-line summary / description (carried into the spec draft + fed to the generator). */
1898
+ summary: string;
1899
+ /** The Phase-1 complexity level — scales the depth budget (SC3). */
1900
+ level: ComplexityLevel;
1901
+ }
1902
+ /** Why a brainstorm halted — the closed no-go set handed to a human. */
1903
+ type HaltReason = 'low-confidence' | 'error';
1904
+ /**
1905
+ * The single outcome of a brainstorm run (SC1): either a clean COMPLETION carrying the spec
1906
+ * draft, or a HALT carrying the fork it stopped at + the reason. Exactly one of the two.
1907
+ * A halt is a REAL handoff — never a rubber-stamped stub (proposal §"a halt is a real
1908
+ * handoff, not a rubber stamp").
1909
+ */
1910
+ type BrainstormOutcome = {
1911
+ kind: 'completed';
1912
+ spec: SpecDraft;
1913
+ } | {
1914
+ kind: 'halted';
1915
+ fork: Fork;
1916
+ reason: HaltReason;
1917
+ detail: string;
1918
+ };
1919
+
1920
+ /**
1921
+ * Drive an autonomous brainstorm for one item. Returns exactly one `BrainstormOutcome`
1922
+ * (SC1): `completed{ spec }` when every explored fork was confidently recommended, or
1923
+ * `halted{ fork, reason }` at the first fork it couldn't. NEVER throws (SC5).
1924
+ *
1925
+ * @param input the item identity + text + Phase-1 level
1926
+ * @param generator the injected fork-decision seam (the thing that calls the model)
1927
+ * @param depth the bounded fork budget (SC3 — scaled from the complexity level upstream)
1928
+ */
1929
+ declare function runAutoBrainstorm(input: BrainstormInput, generator: ForkGenerator, depth: DepthBudget): Promise<BrainstormOutcome>;
1930
+
1931
+ /** Ordinal rank of each complexity band; a positive delta = the diff came in harder. */
1932
+ declare const LEVEL_RANK: Record<ComplexityLevel, number>;
1933
+ /**
1934
+ * Blast-radius overrun tolerance. The actual blast radius may exceed the predicted
1935
+ * scope estimate by up to `BLAST_TOLERANCE_FACTOR×` PLUS `BLAST_TOLERANCE_ABS` before
1936
+ * it counts as over-scope. The additive floor keeps a tiny predicted scope (e.g. 1–2)
1937
+ * from tripping on ordinary noise; the factor bounds the overrun on larger estimates.
1938
+ * Conservative on purpose (plan §Concerns: bias `exceededBy` toward flagging).
1939
+ */
1940
+ declare const BLAST_TOLERANCE_FACTOR = 1.5;
1941
+ declare const BLAST_TOLERANCE_ABS = 2;
1942
+ /** The comparator's verdict for one graded item. */
1943
+ interface RetrospectiveComparison {
1944
+ /** True iff the actual diff stayed WITHIN the predicted band + scope (SC2). */
1945
+ matched: boolean;
1946
+ /**
1947
+ * Mispredict magnitude. `0` when matched. When over-scope it is the level-band
1948
+ * delta (≥ 1) when the level exceeded, else `1` for a blast-only overrun — always
1949
+ * a positive integer so a graded outcome carries a legible severity.
1950
+ */
1951
+ exceededBy: number;
1952
+ /** `verify` on a match (surface for human verify per stage); `block-escalate` on a mismatch/error. */
1953
+ action: 'verify' | 'block-escalate';
1954
+ }
1955
+ /** Tunable comparator thresholds (wired from `roadmap.autoTriage.thresholds`, SC2). */
1956
+ interface RetrospectiveConfig {
1957
+ /**
1958
+ * The level-band delta that counts as a mispredict. Default 1 (any band over the
1959
+ * prediction blocks). Raising it tolerates a wider band drift before escalating —
1960
+ * conservative default keeps the honesty check tight (plan §Concerns).
1961
+ */
1962
+ exceededByBands: number;
1963
+ }
1964
+ /** The default comparator config: any band over the prediction is a mispredict. */
1965
+ declare const DEFAULT_RETROSPECTIVE_CONFIG: RetrospectiveConfig;
1966
+ /**
1967
+ * Compare the stored pre-diff prediction to the full-strength post-diff verdict.
1968
+ *
1969
+ * Returns `{ matched, exceededBy, action }`. Match ⇒ `verify`; mismatch ⇒
1970
+ * `block-escalate`. A missing/garbled/invalid prediction OR actual fails safe to
1971
+ * `block-escalate` (SC7) — absence is never a pass.
1972
+ */
1973
+ declare function compareToPrediction(prediction: TriagePrediction | undefined | null, postDiffVerdict: ComplexityVerdict | undefined | null, config?: RetrospectiveConfig): RetrospectiveComparison;
1974
+
1975
+ /** The autonomy-ratchet stages v1 can resolve. 3/4 are deferred post-v1 (SC4). */
1976
+ type V1Stage = 1 | 2;
1977
+ /** v1's ceiling: the resolver never returns above this (SC4 — stages 3/4 deferred). */
1978
+ declare const V1_MAX_STAGE: 2;
1979
+ /** One graded outcome for a shape. `matched` is the grade; `ts` fixes chronology. */
1980
+ interface RatchetOutcome {
1981
+ /** True iff the post-diff verdict stayed within the prediction (the comparator's `matched`). */
1982
+ matched: boolean;
1983
+ /**
1984
+ * ISO timestamp the outcome was graded (FOLLOW-UP 1 / safety). The mispredict-reset keys on the
1985
+ * CHRONOLOGICALLY-latest outcome, so `resolveStage` sorts by `ts` first. Optional for
1986
+ * back-compat: the sort is a stable no-op when `ts` is absent (already-chronological callers).
1987
+ */
1988
+ ts?: string;
1989
+ }
1990
+ /** Advancement rules. Conservative defaults; the caller may override per policy. */
1991
+ interface RatchetConfig {
1992
+ /** Minimum trailing-window success-rate required to advance from stage 1 → 2 (SC6). */
1993
+ threshold: number;
1994
+ /** Minimum number of graded outcomes in the window before advancement is even considered. */
1995
+ minSample: number;
1996
+ /** Trailing-window size: only the most recent `window` outcomes count (recency ⇒ a mispredict resets). */
1997
+ window: number;
1998
+ }
1999
+ /**
2000
+ * Conservative default policy: a shape must show ≥ 90% matches over its most recent
2001
+ * 10 graded outcomes (at least `minSample` of them) before it earns stage 2. A single
2002
+ * recent mispredict inside a 10-wide window is 90% → still at the edge; two drop it below.
2003
+ */
2004
+ declare const DEFAULT_RATCHET_CONFIG: RatchetConfig;
2005
+ /**
2006
+ * Resolve the autonomy stage a shape has EARNED from its graded history.
2007
+ *
2008
+ * Returns stage 1 (the safe default) at cold-start, below `minSample`, or whenever
2009
+ * the trailing-window success-rate is under `threshold` (a recent mispredict resets).
2010
+ * Returns stage 2 once the evidence clears the bar. NEVER returns above
2011
+ * {@link V1_MAX_STAGE} (SC4) — the value is clamped as a belt-and-suspenders guard so
2012
+ * a future config change can't accidentally leak a deferred stage.
2013
+ */
2014
+ declare function resolveStage(history: readonly RatchetOutcome[], config?: RatchetConfig): V1Stage;
2015
+
2016
+ /**
2017
+ * The escalation categories that may auto-execute (mirror of the orchestrator's
2018
+ * `EscalationConfig.autoExecute` default — proposal §"Dispatch path" reuses the
2019
+ * shipped escalation categories rather than inventing a parallel taxonomy). An
2020
+ * item whose category is NOT in this set stays human even after a human go (SC3):
2021
+ * `guided-change` is signal-gated and `full-exploration` is always-human.
2022
+ *
2023
+ * Defined as a frozen set here (not imported from orchestrator) to keep this gate
2024
+ * in the intelligence layer; the orchestrator's escalation default is the source of
2025
+ * truth for the VALUES, and the T3 wiring is where the two are reconciled against
2026
+ * the live `config.agent.escalation.autoExecute`.
2027
+ */
2028
+ declare const AUTO_EXECUTE_CATEGORIES: ReadonlySet<ScopeTier>;
2029
+ /**
2030
+ * One ready candidate presented to the go/no-go gate. Built in the wiring layer from
2031
+ * a Phase-2 spec-bearing, re-scored-dispatchable item; the gate reads only the three
2032
+ * fields that decide authorization.
2033
+ */
2034
+ interface GoNoGoCandidate {
2035
+ /** Stable item key (roadmap External-ID). */
2036
+ externalId: string;
2037
+ /** The item's escalation category (the routing bucket it fell into). */
2038
+ category: ScopeTier;
2039
+ /**
2040
+ * Whether a human has EXPLICITLY approved this item in the batched go/no-go. The
2041
+ * quiet linchpin of stage 1: absent this flag no item is ever approved — the gate
2042
+ * never manufactures a go. Set by the `triage approve` command (Phase 3 T4).
2043
+ */
2044
+ humanApproved: boolean;
2045
+ }
2046
+ /** Why a candidate was held rather than approved. A closed, legible set (SC-F2 style). */
2047
+ type HoldReason =
2048
+ /** The candidate's EFFECTIVE stage is deferred post-v1 (3-4); v1 caps at stage 2. */
2049
+ 'ratchet-stage-unsupported'
2050
+ /** The item's category is not auto-executable (guided-change / full-exploration). */
2051
+ | 'not-auto-executable'
2052
+ /** Auto-executable, but no human has given the go yet (stage-1 default hold). */
2053
+ | 'awaiting-human-go';
2054
+ /** A held candidate: the item plus the single legible reason it did not pass. */
2055
+ interface HeldCandidate {
2056
+ externalId: string;
2057
+ category: ScopeTier;
2058
+ reason: HoldReason;
2059
+ }
2060
+ /** An approved candidate carrying the EVIDENCE-DERIVED stage its shape earned (SC6). */
2061
+ interface ApprovedCandidate extends GoNoGoCandidate {
2062
+ /**
2063
+ * The effective autonomy stage this candidate's SHAPE earned from its recorded history
2064
+ * (`min(resolveStage(history), configuredCeiling, 2)`). 1 = human-before-execution (the
2065
+ * cold-start default); 2 = auto-execute + required human-verify (v1's ceiling). This governs
2066
+ * only DOWNSTREAM match-handling/advancement — NOT the authorization above (which is stage-
2067
+ * independent: humanApproved AND auto-executable). The marker stamps it onto the prediction.
2068
+ */
2069
+ effectiveStage: 1 | 2;
2070
+ }
2071
+ /** The gate's output: the partition of the ready set into approved vs held. */
2072
+ interface GoNoGoDecision {
2073
+ /** Items cleared for the marker: human-approved AND auto-executable, with the earned stage. */
2074
+ approved: ApprovedCandidate[];
2075
+ /** Everything else, each carrying the reason it was held to a human. */
2076
+ held: HeldCandidate[];
2077
+ }
2078
+ /**
2079
+ * One ready candidate presented to the PER-SHAPE go/no-go gate: the base candidate plus the
2080
+ * effective autonomy stage its shape earned from recorded evidence. The caller resolves the
2081
+ * stage per-shape (via the pure `resolveStage` over that shape's history) so the ratchet
2082
+ * advances INDEPENDENTLY per shape (SC6), never as one batch stage.
2083
+ */
2084
+ interface StagedGoNoGoCandidate extends GoNoGoCandidate {
2085
+ /** `min(resolveStage(historyForShape), configuredCeiling, 2)`. Cold-start ⇒ 1. */
2086
+ effectiveStage: RatchetStage;
2087
+ }
2088
+ /**
2089
+ * Pure go/no-go partition with a PER-CANDIDATE evidence-derived stage (SC6).
2090
+ *
2091
+ * The AUTHORIZATION rule is stage-INDEPENDENT and unchanged from Phase 3: an item is
2092
+ * `approved` iff its category is in {@link AUTO_EXECUTE_CATEGORIES} AND a human explicitly
2093
+ * approved it. The stage does NOT relax this — the human-go requirement holds at every stage.
2094
+ * The stage only rides ALONG on an approved item (`effectiveStage`) to govern downstream
2095
+ * match-handling/advancement; a candidate whose earned stage is deferred post-v1 (3-4) is
2096
+ * refused as `ratchet-stage-unsupported` (a fail-safe belt: the caller already clamps to ≤ 2,
2097
+ * so this should be unreachable, but a mis-set stage must never loosen the gate).
2098
+ *
2099
+ * Ordering of the hold reasons is deliberate and matches Phase 3: the stage guard is checked
2100
+ * first (a deferred stage refuses regardless), then the category gate (structural), then the
2101
+ * human-go gate — so an approved non-autoExecute item still reads `not-auto-executable`.
2102
+ */
2103
+ declare function resolveGoNoGoStaged(candidates: readonly StagedGoNoGoCandidate[]): GoNoGoDecision;
2104
+ /**
2105
+ * Pure go/no-go partition for a UNIFORM ratchet stage (Phase 3 shape, retained for callers
2106
+ * that have not yet resolved per-shape evidence). Delegates to {@link resolveGoNoGoStaged} by
2107
+ * stamping the SAME `stage` on every candidate — so the authorization + hold-reason ordering
2108
+ * is defined in exactly one place. Passing a deferred stage (3-4) refuses the whole batch, and
2109
+ * stage 1 reproduces Phase-3 behavior byte-for-byte.
2110
+ */
2111
+ declare function resolveGoNoGo(candidates: readonly GoNoGoCandidate[], stage: RatchetStage): GoNoGoDecision;
2112
+
2113
+ export { ACCEPTANCE_EVAL_SYSTEM_PROMPT, AUTO_EXECUTE_CATEGORIES, type AcceptanceEvalInput, AcceptanceEvaluator, type AcceptanceEvaluatorOptions, type AcceptanceVerdict, type AffectedSystem, type AnalysisProvider, type AnalysisRequest, type AnalysisResponse, AnthropicAnalysisProvider, type ApprovedCandidate, type Authority, BLAST_TOLERANCE_ABS, BLAST_TOLERANCE_FACTOR, type BlastRadius, type BlindSpot, type BrainstormInput, type BrainstormOutcome, type CanaryAdapter, type CanaryDegradeReason, type CanaryExec, type CanaryFinding, type CanaryProbe, type ClassifyInput, ClaudeCliAnalysisProvider, type ComplexityScore, type ComplexitySignals, type Confidence, DEFAULT_DEGRADE_AT_PCT, DEFAULT_RATCHET_CONFIG, DEFAULT_RETROSPECTIVE_CONFIG, DEPTH_BY_LEVEL, type DepthBudget, type EnrichedSpec, type EscalationCategory, type ExecutionOutcome, ExecutionOutcomeConnector, type ExpertiseLevel, type Finding, type Fork, type ForkConfidence, type ForkDecision, type ForkGenerator, type FrameworkRecommendation, type GitHubIssue, type GoNoGoCandidate, type GoNoGoDecision, type HoldReason as GoNoGoHoldReason, type GraphScope, GraphValidator, type HaltReason, type HeldCandidate, type HoldReason$1 as HoldReason, IntelligencePipeline, type JiraIssue, type JudgedAgainst, LEVEL_RANK, type LeverResult, type LinearIssue, type LlmAcceptanceVerdict, type LlmVerdict, type ManualInput, type Measurability, OUTCOME_EVAL_SYSTEM_PROMPT, OpenAICompatibleAnalysisProvider, type OpenDecision, type OutcomeEvalInput, OutcomeEvaluator, type OutcomeEvaluatorOptions, type OutcomeIngestResult, type OutcomeVerdict, type PersonaEffectivenessScore, type PersonaRecommendation, PeslSimulator, type Phase, type PrecedentLookup, type PrecedentRate, type PreprocessResult, type ProbeConfig, type ProbeDeps, type ProbeInput, type ProbeLevers, type ProfileStore, RANK_TIER, type RankableCandidate, type RatchetConfig, type RatchetOutcome, type RatchetStage, type RawWorkItem, type ResolvedEntity, type ResolvedSection, type RetrospectiveComparison, type RetrospectiveConfig, SENSITIVE_BLAST_THRESHOLD, STATIC_WEIGHTS, type ScopeEstimate, type SimulationResult, type SpecDraft, type SpecializationEntry, type SpecializationProfile, type SpecializationScore, type StagedGoNoGoCandidate, type StaticVerdict, TIER_RANK, type TaskType, type TemporalConfig, type TiebreakResult, type TriageOutcome, type TriagePrediction, type TriageRecord, type TriageVerdict, type V1Stage, V1_MAX_STAGE, type Verdict, type WeightedRecommendation, acceptanceVerdictSchema, aggregatePrecedent, applyBudgetClamp, baseTier, blastRadiusVeto, buildUserPrompt as buildAcceptanceUserPrompt, buildSpecializationProfile, buildUserPrompt$1 as buildUserPrompt, classify, compareToPrediction, computeExpertiseLevel, computeHistoricalComplexity, computePersonaEffectiveness, computeSemanticComplexity, computeSpecialization, computeStructuralComplexity, createCanaryAdapter, decayWeight, depthForLevel, deriveAcceptanceAuthority, deriveAuthority, deriveRequiredTier, detectBlindSpots, dispatchableShapeKey, enrich, extractEntities, findingSchema, githubToRawWorkItem, jiraToRawWorkItem, linearToRawWorkItem, llmTiebreak, loadProfiles, manualToRawWorkItem, pilotScore, precedentLookupFromRecords, rankTriageCandidates, recommendPersona, refreshProfiles, resolveGoNoGo, resolveGoNoGoStaged, resolveSection, resolveStage, runAutoBrainstorm, runGraphOnlyChecks, runLlmSimulation, runScopingProbe, runStaticPass, saveProfiles, score as scoreCML, scoreToConcernSignals, serializeSignals, shapeKey, temporalSuccessRate, toRawWorkItem, verdictSchema, weightedRecommendPersona };