import type { StateComparison } from '../architecture-state.js'; import type { Diagnostic, GraphClaim, ResolvedProfileContext, SemanticGraph } from '../compiler.js'; import { type EvidenceResult } from '../evidence.js'; import { type InterrogationReport } from '../interrogate-command.js'; import { type NextSubject } from '../next-command.js'; import { type ConceptKind } from '../profile.js'; import { type ProjectionResult } from '../projection.js'; import { type ReconciliationFinding, type ReconciliationReport } from '../reconciliation.js'; import { type CheckCounts } from './check.js'; import { type Compiled, type ToolResult, type ToolWorkspace } from './workspace.js'; /** * `yarramate ask`, mode by mode, over a store (ADR 0156). The result * documents are the published `yarramate/ask-result/v1` shapes, exactly as * `ask --json` prints them; the CLI renders its human forms from these same * values, so the two surfaces cannot drift. The modes that need git * (`--changed`) or stay CLI-only (`--advise`, `--where`, `--compare`) keep * their types here so the CLI's union is one type. */ export interface ConceptEntry { readonly id: string; readonly kind: string; readonly name?: string; readonly status?: string; readonly description?: string; readonly aka?: readonly string[]; } export interface OpenQuestionRef { readonly wave: string; readonly id: string; readonly authority: 'human' | 'agent' | 'either'; readonly question: string; readonly materiality: string; readonly subject?: string; } export interface AskResultBase { readonly format: 'yarramate/ask-result/v1'; readonly workspace: string; } /** * One relationship kind as `--kinds` reports it. The aspect lists are the * shadow the ArchiMate table casts on the aspect axis - a necessary * condition, never the rule; the rule is `relationshipMatrix`. */ export interface RelationshipKindSummary { readonly id: string; readonly intent: string; readonly sourceAspects: readonly string[]; readonly targetAspects: readonly string[]; } /** The vendored table itself, packed exactly as the generated module holds it (ADR 0097). */ export interface RelationshipMatrixSummary { readonly standard: string; readonly letters: Readonly>; readonly kinds: readonly string[]; readonly rows: Readonly>; } export interface NeighbourhoodOmission { readonly cap: number; readonly kept: number; readonly omitted: number; readonly omittedBySeed: readonly { readonly seed: string; readonly omitted: number; }[]; } export type AskOrientation = AskResultBase & { readonly mode: 'orientation'; readonly ok: boolean; readonly check: { readonly ok: boolean; readonly diagnostics: readonly Diagnostic[]; readonly counted?: CheckCounts; }; readonly reconciliation?: ReconciliationReport['summary']; readonly design?: { readonly catalogue: string; readonly open: number; }; readonly backlog: { readonly planned: readonly NextSubject[]; readonly current: readonly ConceptEntry[]; readonly retired: readonly ConceptEntry[]; }; }; export type AskRoster = AskResultBase & { readonly mode: 'roster'; readonly total: number; readonly subjects: readonly ConceptEntry[]; }; export type AskSlice = AskResultBase & { readonly mode: 'slice'; readonly addressing: 'free-text' | 'subjects' | 'projection' | 'changed'; readonly topic?: string; readonly seeds?: readonly string[]; readonly matched?: number; /** * Every concept a term touched, ranked, present on a free-text slice (#569). * The seeds are the first few of these; a caller with a judgment to spend * reorders the list and asks again with `subjects` addressing. */ readonly candidates?: readonly SeedCandidate[]; readonly changed?: { readonly range: string; readonly concepts: readonly string[]; readonly relationships: readonly string[]; }; readonly coverage?: { readonly projections: number; readonly uncovered: readonly string[]; }; readonly neighbourhood?: NeighbourhoodOmission; readonly result: ProjectionResult; /** * The text the CLI prints for the same call: the brief, or the budgeted * context when a budget was given. A hosted tool answers an agent with * text and should not re-render on its side of the seam. Additive to the * published document (ADR 0156); absent from the git-derived slices the * CLI alone produces. */ readonly rendered?: string; }; export type AskAdvice = AskResultBase & { readonly mode: 'advice'; readonly topic: string; readonly seeds: readonly string[]; readonly matched: number; readonly slice: string; readonly neighbourhood?: NeighbourhoodOmission; readonly openQuestions: readonly OpenQuestionRef[]; readonly reconciliation?: { readonly summary: ReconciliationReport['summary']; readonly findings: readonly ReconciliationFinding[]; }; }; export type AskWhere = AskResultBase & { readonly mode: 'where'; readonly addressing: 'free-text' | 'subjects'; readonly topic: string; readonly seeds: readonly string[]; readonly matched: number; readonly located: readonly { readonly subject: string; readonly observations: readonly { readonly uri: string; readonly result: EvidenceResult; readonly provider: string; readonly message?: string; }[]; }[]; readonly coverage: { readonly unobserved: readonly string[]; readonly note: string; }; }; export type AskNext = AskResultBase & { readonly mode: 'next'; readonly subjects: readonly NextSubject[]; }; export type AskOpen = AskResultBase & { readonly mode: 'open'; readonly report: InterrogationReport; }; export type AskCompare = AskResultBase & { readonly mode: 'compare'; readonly comparison: StateComparison; }; export type AskKinds = AskResultBase & { readonly mode: 'kinds'; readonly conceptKinds: readonly ConceptKind[]; readonly relationshipKinds: readonly RelationshipKindSummary[]; readonly relationshipMatrix: RelationshipMatrixSummary; readonly extensions: readonly { readonly id: string; readonly type: 'concept' | 'relationship'; readonly lineage: readonly string[]; }[]; }; export type AskResult = AskOrientation | AskRoster | AskSlice | AskAdvice | AskWhere | AskNext | AskOpen | AskCompare | AskKinds; export declare const claimValue: (claims: readonly GraphClaim[], subject: string, predicate: string) => string | undefined; export declare const conceptEntries: (graph: SemanticGraph) => readonly ConceptEntry[]; /** * How many ranked candidates `resolveSeeds` hands back beside the seeds. Thirty * is the shortlist the #569 measurement reranked, and it is a cap rather than a * target: most queries match fewer. */ export declare const candidateLimit = 30; export interface SeedCandidate { readonly id: string; /** How many distinct query terms this concept's text contains. The whole of the ranking. */ readonly terms: number; } export interface SeedResolution { readonly addressing: 'free-text' | 'subjects'; readonly seeds: readonly string[]; readonly matched: number; /** * Every concept a term touched, ranked, not just the handful that seeded the * slice (#569). * * The term count finds the right subject and then buries it. Measured on the * Halcyon showcase against 32 questions written by someone other than the * author: the subject the asker meant was inside this list 87% of the time * and was the FIRST seed only 43% of the time. Retrieval was not the * weakness; ordering was. * * The engine cannot fix that on its own, because deciding which of several * term-matching concepts actually answers a question is a judgment and this * is a deterministic CLI (ADR 0059). So it hands the list over instead. A * caller with a judgment to spend - an agent, a host with a decision model - * reorders these and calls back with `subjects` addressing, which already * exists. A caller with none uses `seeds` exactly as before. * * Capped, so a one-word query against a large workspace cannot return the * whole record: `candidateLimit`, which a caller may raise. */ readonly candidates: readonly SeedCandidate[]; } export declare const resolveSeeds: (terms: readonly string[], entries: readonly ConceptEntry[], options?: { readonly candidates?: number; }) => SeedResolution; export declare const defaultNeighbourCap = 12; export interface SliceEvaluation { readonly result: ProjectionResult; readonly neighbourhood?: NeighbourhoodOmission; } export declare const sliceProjection: (graph: SemanticGraph, seeds: readonly string[], title: string, profileContext: ResolvedProfileContext | undefined, neighbourCap: number) => SliceEvaluation; /** The brief, or the budgeted context when a budget was given: what the CLI prints. */ export declare const renderSlice: (evaluated: ProjectionResult, compiled: Pick, budget: number | undefined) => string; /** The declarable vocabulary, as `--kinds` reports it. */ export declare const kindsOf: (workspaceId: string, profileContext: ResolvedProfileContext) => AskKinds; /** What orientation needs beside its document: the report, for the CLI's sentence. */ export interface OrientationDetailed { readonly result: AskOrientation; /** Absent when the check failed: nothing was compiled. */ readonly report?: Omit; } /** `yarramate ask --json` with no query: check verdict, drift summary, open count, backlog. */ export declare const askOrientationDetailed: (workspace: ToolWorkspace) => ToolResult; export declare const askOrientation: (workspace: ToolWorkspace) => ToolResult; export interface RosterOptions { /** Substring match on the kind id, as `--kind`. */ readonly kind?: string; readonly status?: 'planned' | 'current' | 'retired'; } /** The roster plus every entry, for the CLI's "n of total" line. */ export interface RosterDetailed { readonly result: AskRoster; readonly entries: readonly ConceptEntry[]; } export declare const askRosterDetailed: (workspace: ToolWorkspace, options?: RosterOptions) => ToolResult; /** `yarramate ask --subjects [--kind] [--status] --json`. */ export declare const askRoster: (workspace: ToolWorkspace, options?: RosterOptions) => ToolResult; /** `yarramate ask --kinds --json`. */ export declare const askKinds: (workspace: ToolWorkspace) => ToolResult; /** `yarramate ask --next --json`. */ export declare const askNext: (workspace: ToolWorkspace) => ToolResult; /** `yarramate ask --open --json`. */ export declare const askOpen: (workspace: ToolWorkspace) => ToolResult; /** * What a slice is asked about. Free text matches ids, names and * descriptions; subject ids address precisely; a projection path names a * saved view in the store. The CLI decides between the three by looking at * the filesystem and the id syntax; a tool says which it means. */ export type SliceQuery = { readonly text: string; } | { readonly subjects: readonly string[]; } | { readonly projection: string; }; export interface SliceOptions { /** Approximate token budget; renders the budgeted context instead of the brief. */ readonly budget?: number; /** Neighbour cap for seeded slices (text and subjects); 0 lifts it. Refused with a projection. */ readonly neighbours?: number; } /** `yarramate ask "" | ... | [--budget] [--neighbours]`. */ export declare const askSlice: (workspace: ToolWorkspace, query: SliceQuery, options?: SliceOptions) => ToolResult;