@harness-engineering/intelligence 0.3.0 → 0.4.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.mts CHANGED
@@ -741,7 +741,7 @@ declare const OUTCOME_EVAL_SYSTEM_PROMPT = "You are a post-execution outcome jud
741
741
  * a 4-backtick fence so a triple-backtick sequence inside the diff cannot close
742
742
  * the fence early.
743
743
  */
744
- declare function buildUserPrompt(section: string, diff: string, testOutput: string): string;
744
+ declare function buildUserPrompt$1(section: string, diff: string, testOutput: string): string;
745
745
 
746
746
  /**
747
747
  * Result of resolving the judgment section from a spec's markdown.
@@ -828,6 +828,171 @@ declare class OutcomeEvaluator {
828
828
  private persistOutcome;
829
829
  }
830
830
 
831
+ /**
832
+ * acceptance-eval contract types — the upstream twin of outcome-eval.
833
+ *
834
+ * `authority` is DERIVED in TypeScript from (measurability, confidence) via
835
+ * `deriveAcceptanceAuthority` in `./authority.js`. It is NEVER read from the
836
+ * LLM response — see `acceptanceVerdictSchema` in `./prompts.js`, which omits
837
+ * it. `Confidence`, `JudgedAgainst`, and `Authority` are REUSED from the
838
+ * outcome-eval module — not forked — consistent with the imported section-resolver.
839
+ */
840
+
841
+ /** (c) the measurability gate dimension. */
842
+ type Measurability = 'MEASURABLE' | 'NOT_MEASURABLE' | 'INCONCLUSIVE';
843
+ /** A single advisory observation about one criterion or behavior. */
844
+ interface Finding {
845
+ /** The specific criterion or user-visible behavior this finding references. */
846
+ target: string;
847
+ /** The advisory observation (e.g. 'not observable', 'no covering test'). */
848
+ message: string;
849
+ }
850
+ interface AcceptanceEvalInput {
851
+ /** Absolute or repo-relative path to the spec markdown. */
852
+ specPath: string;
853
+ /** Pre-resolved judgment section; otherwise the section-resolver runs. */
854
+ specSection?: string;
855
+ /**
856
+ * Located test snippets for coverage responsibility (b). Optional: absence
857
+ * degrades (b) coverageFindings to advisory-empty and never affects the
858
+ * (c) measurability gate.
859
+ */
860
+ testContent?: string;
861
+ }
862
+ interface AcceptanceVerdict {
863
+ measurability: Measurability;
864
+ confidence: Confidence;
865
+ /** DERIVED in TS from (measurability, confidence); never from the LLM. */
866
+ authority: Authority;
867
+ /** Which spec section resolved. */
868
+ judgedAgainst: JudgedAgainst;
869
+ /** (a) advisory — observability / testability / completeness critique. */
870
+ criteriaFindings: Finding[];
871
+ /** (b) advisory — user-visible behaviors with no covering test. */
872
+ coverageFindings: Finding[];
873
+ rationale: string;
874
+ }
875
+
876
+ /**
877
+ * Pure mapping from (measurability, confidence) to gate authority.
878
+ *
879
+ * Blocking iff a spec is judged NOT_MEASURABLE with high confidence — i.e. it
880
+ * objectively lacks measurable success criteria; every other combination,
881
+ * including all INCONCLUSIVE and MEASURABLE cases, is advisory. Missing or
882
+ * uncertain inputs never punish the spec.
883
+ *
884
+ * This function is the false-positive-critical seam. Authority is computed
885
+ * here in TypeScript and is NEVER trusted from the LLM response.
886
+ */
887
+ declare function deriveAcceptanceAuthority(measurability: Measurability, confidence: Confidence): Authority;
888
+
889
+ /** A single advisory finding. `.strict()` rejects unexpected keys. */
890
+ declare const findingSchema: z.ZodObject<{
891
+ target: z.ZodString;
892
+ message: z.ZodString;
893
+ }, "strict", z.ZodTypeAny, {
894
+ message: string;
895
+ target: string;
896
+ }, {
897
+ message: string;
898
+ target: string;
899
+ }>;
900
+ /**
901
+ * Zod schema for the LLM verdict response.
902
+ *
903
+ * `authority` is intentionally ABSENT: it is derived in TypeScript by
904
+ * `deriveAcceptanceAuthority` and must never be supplied by the model. The
905
+ * schema is `.strict()`, so an injected `authority` (or any other extra key)
906
+ * is rejected at the parse boundary rather than silently passing through.
907
+ */
908
+ declare const acceptanceVerdictSchema: z.ZodObject<{
909
+ measurability: z.ZodEnum<["MEASURABLE", "NOT_MEASURABLE", "INCONCLUSIVE"]>;
910
+ confidence: z.ZodEnum<["low", "medium", "high"]>;
911
+ rationale: z.ZodString;
912
+ criteriaFindings: z.ZodArray<z.ZodObject<{
913
+ target: z.ZodString;
914
+ message: z.ZodString;
915
+ }, "strict", z.ZodTypeAny, {
916
+ message: string;
917
+ target: string;
918
+ }, {
919
+ message: string;
920
+ target: string;
921
+ }>, "many">;
922
+ coverageFindings: z.ZodArray<z.ZodObject<{
923
+ target: z.ZodString;
924
+ message: z.ZodString;
925
+ }, "strict", z.ZodTypeAny, {
926
+ message: string;
927
+ target: string;
928
+ }, {
929
+ message: string;
930
+ target: string;
931
+ }>, "many">;
932
+ }, "strict", z.ZodTypeAny, {
933
+ confidence: "low" | "medium" | "high";
934
+ rationale: string;
935
+ measurability: "INCONCLUSIVE" | "MEASURABLE" | "NOT_MEASURABLE";
936
+ criteriaFindings: {
937
+ message: string;
938
+ target: string;
939
+ }[];
940
+ coverageFindings: {
941
+ message: string;
942
+ target: string;
943
+ }[];
944
+ }, {
945
+ confidence: "low" | "medium" | "high";
946
+ rationale: string;
947
+ measurability: "INCONCLUSIVE" | "MEASURABLE" | "NOT_MEASURABLE";
948
+ criteriaFindings: {
949
+ message: string;
950
+ target: string;
951
+ }[];
952
+ coverageFindings: {
953
+ message: string;
954
+ target: string;
955
+ }[];
956
+ }>;
957
+ type LlmAcceptanceVerdict = z.infer<typeof acceptanceVerdictSchema>;
958
+ /**
959
+ * System prompt for acceptance-eval. Conservative-confidence posture mirrors
960
+ * outcome-eval: default to medium; high requires naming a specific criterion;
961
+ * bias toward advisory. `authority` is derived in TypeScript and must never be
962
+ * supplied by the model — the schema is `.strict()` and rejects it.
963
+ */
964
+ declare const ACCEPTANCE_EVAL_SYSTEM_PROMPT = "You are a PRE-execution acceptance-criteria judge. Given a spec acceptance section (and optionally located test snippets), assess three things:\n(a) criteria quality \u2014 are the success criteria observable, testable, and complete? (advisory findings)\n(b) coverage \u2014 do any user-visible behaviors lack a covering test? (advisory findings)\n(c) measurability \u2014 does the spec state MEASURABLE, NOT_MEASURABLE, or is it INCONCLUSIVE on whether any measurable success criteria exist at all?\n\nConfidence calibration (be conservative \u2014 false alarms are costly):\n- Default to \"medium\" confidence.\n- Use \"high\" ONLY when you can name a SPECIFIC criterion (or its absence) and quote or paraphrase it in the rationale.\n- Use \"low\" when the section is ambiguous, partial, or insufficient to judge.\n- Bias toward advisory caution: if unsure between two confidence levels, choose the lower one.\n\nRules:\n- \"measurability\" is NOT_MEASURABLE only when the section states no observable, testable success criterion at all.\n- \"criteriaFindings\" holds advisory (a) observations; \"coverageFindings\" holds advisory (b) observations; both may be empty.\n- Do NOT emit an \"authority\" field. Authority is computed downstream in TypeScript from (measurability, confidence) and must never come from you.\n\nReturn your judgment using the structured_output tool.";
965
+ /**
966
+ * Build the user prompt from the resolved spec section body and optional
967
+ * located test snippets. Test content is clamped to PROMPT_FIELD_MAX_CHARS and
968
+ * wrapped in a 4-backtick fence so an inner ``` cannot close the fence early.
969
+ */
970
+ declare function buildUserPrompt(section: string, testContent?: string): string;
971
+
972
+ interface AcceptanceEvaluatorOptions {
973
+ /** Override model for the acceptance-eval LLM call. */
974
+ model?: string;
975
+ }
976
+ /**
977
+ * Pre-execution acceptance-criteria judge — the upstream twin of
978
+ * OutcomeEvaluator. Built on the cli AnalysisProvider. The LLM returns only
979
+ * measurability/confidence/criteriaFindings/coverageFindings/rationale;
980
+ * `authority` is derived in TypeScript and never read from the model.
981
+ *
982
+ * Unlike OutcomeEvaluator it holds no GraphStore: there is no acceptance
983
+ * outcome node type and Phase 1 does not persist (see plan D-P1-3).
984
+ */
985
+ declare class AcceptanceEvaluator {
986
+ private readonly provider;
987
+ private readonly options;
988
+ constructor(provider: AnalysisProvider, options?: AcceptanceEvaluatorOptions);
989
+ evaluate(input: AcceptanceEvalInput): Promise<AcceptanceVerdict>;
990
+ private judge;
991
+ private degradedVerdict;
992
+ private resolveJudgmentSection;
993
+ private buildVerdict;
994
+ }
995
+
831
996
  /**
832
997
  * Compute historical complexity from past execution outcomes in the graph.
833
998
  *
@@ -1168,4 +1333,4 @@ declare function saveProfiles(projectRoot: string, store: ProfileStore): void;
1168
1333
  */
1169
1334
  declare function refreshProfiles(projectRoot: string, graphStore: GraphStore, opts?: Omit<SpecializationOptions, 'persona'>): ProfileStore;
1170
1335
 
1171
- export { 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, ClaudeCliAnalysisProvider, type ComplexityScore, type Confidence, type EnrichedSpec, type ExecutionOutcome, ExecutionOutcomeConnector, type ExpertiseLevel, type FrameworkRecommendation, type GitHubIssue, GraphValidator, IntelligencePipeline, type JiraIssue, type JudgedAgainst, type LinearIssue, type LlmVerdict, type ManualInput, OUTCOME_EVAL_SYSTEM_PROMPT, OpenAICompatibleAnalysisProvider, type OutcomeEvalInput, OutcomeEvaluator, type OutcomeEvaluatorOptions, type OutcomeIngestResult, type OutcomeVerdict, type PersonaEffectivenessScore, type PersonaRecommendation, PeslSimulator, type PreprocessResult, type ProfileStore, type RawWorkItem, type ResolvedSection, type SimulationResult, type SpecializationEntry, type SpecializationProfile, type SpecializationScore, type TaskType, type TemporalConfig, type Verdict, type WeightedRecommendation, buildSpecializationProfile, buildUserPrompt, computeExpertiseLevel, computeHistoricalComplexity, computePersonaEffectiveness, computeSemanticComplexity, computeSpecialization, computeStructuralComplexity, createCanaryAdapter, decayWeight, deriveAuthority, detectBlindSpots, enrich, githubToRawWorkItem, jiraToRawWorkItem, linearToRawWorkItem, loadProfiles, manualToRawWorkItem, recommendPersona, refreshProfiles, resolveSection, runGraphOnlyChecks, runLlmSimulation, saveProfiles, score as scoreCML, scoreToConcernSignals, temporalSuccessRate, toRawWorkItem, verdictSchema, weightedRecommendPersona };
1336
+ 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, ClaudeCliAnalysisProvider, type ComplexityScore, type Confidence, 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 PreprocessResult, type ProfileStore, type RawWorkItem, type ResolvedSection, type SimulationResult, type SpecializationEntry, type SpecializationProfile, type SpecializationScore, type TaskType, type TemporalConfig, type Verdict, type WeightedRecommendation, acceptanceVerdictSchema, buildUserPrompt as buildAcceptanceUserPrompt, buildSpecializationProfile, buildUserPrompt$1 as buildUserPrompt, computeExpertiseLevel, computeHistoricalComplexity, computePersonaEffectiveness, computeSemanticComplexity, computeSpecialization, computeStructuralComplexity, createCanaryAdapter, decayWeight, deriveAcceptanceAuthority, deriveAuthority, detectBlindSpots, enrich, findingSchema, githubToRawWorkItem, jiraToRawWorkItem, linearToRawWorkItem, loadProfiles, manualToRawWorkItem, recommendPersona, refreshProfiles, resolveSection, runGraphOnlyChecks, runLlmSimulation, saveProfiles, score as scoreCML, scoreToConcernSignals, temporalSuccessRate, toRawWorkItem, verdictSchema, weightedRecommendPersona };
package/dist/index.d.ts CHANGED
@@ -741,7 +741,7 @@ declare const OUTCOME_EVAL_SYSTEM_PROMPT = "You are a post-execution outcome jud
741
741
  * a 4-backtick fence so a triple-backtick sequence inside the diff cannot close
742
742
  * the fence early.
743
743
  */
744
- declare function buildUserPrompt(section: string, diff: string, testOutput: string): string;
744
+ declare function buildUserPrompt$1(section: string, diff: string, testOutput: string): string;
745
745
 
746
746
  /**
747
747
  * Result of resolving the judgment section from a spec's markdown.
@@ -828,6 +828,171 @@ declare class OutcomeEvaluator {
828
828
  private persistOutcome;
829
829
  }
830
830
 
831
+ /**
832
+ * acceptance-eval contract types — the upstream twin of outcome-eval.
833
+ *
834
+ * `authority` is DERIVED in TypeScript from (measurability, confidence) via
835
+ * `deriveAcceptanceAuthority` in `./authority.js`. It is NEVER read from the
836
+ * LLM response — see `acceptanceVerdictSchema` in `./prompts.js`, which omits
837
+ * it. `Confidence`, `JudgedAgainst`, and `Authority` are REUSED from the
838
+ * outcome-eval module — not forked — consistent with the imported section-resolver.
839
+ */
840
+
841
+ /** (c) the measurability gate dimension. */
842
+ type Measurability = 'MEASURABLE' | 'NOT_MEASURABLE' | 'INCONCLUSIVE';
843
+ /** A single advisory observation about one criterion or behavior. */
844
+ interface Finding {
845
+ /** The specific criterion or user-visible behavior this finding references. */
846
+ target: string;
847
+ /** The advisory observation (e.g. 'not observable', 'no covering test'). */
848
+ message: string;
849
+ }
850
+ interface AcceptanceEvalInput {
851
+ /** Absolute or repo-relative path to the spec markdown. */
852
+ specPath: string;
853
+ /** Pre-resolved judgment section; otherwise the section-resolver runs. */
854
+ specSection?: string;
855
+ /**
856
+ * Located test snippets for coverage responsibility (b). Optional: absence
857
+ * degrades (b) coverageFindings to advisory-empty and never affects the
858
+ * (c) measurability gate.
859
+ */
860
+ testContent?: string;
861
+ }
862
+ interface AcceptanceVerdict {
863
+ measurability: Measurability;
864
+ confidence: Confidence;
865
+ /** DERIVED in TS from (measurability, confidence); never from the LLM. */
866
+ authority: Authority;
867
+ /** Which spec section resolved. */
868
+ judgedAgainst: JudgedAgainst;
869
+ /** (a) advisory — observability / testability / completeness critique. */
870
+ criteriaFindings: Finding[];
871
+ /** (b) advisory — user-visible behaviors with no covering test. */
872
+ coverageFindings: Finding[];
873
+ rationale: string;
874
+ }
875
+
876
+ /**
877
+ * Pure mapping from (measurability, confidence) to gate authority.
878
+ *
879
+ * Blocking iff a spec is judged NOT_MEASURABLE with high confidence — i.e. it
880
+ * objectively lacks measurable success criteria; every other combination,
881
+ * including all INCONCLUSIVE and MEASURABLE cases, is advisory. Missing or
882
+ * uncertain inputs never punish the spec.
883
+ *
884
+ * This function is the false-positive-critical seam. Authority is computed
885
+ * here in TypeScript and is NEVER trusted from the LLM response.
886
+ */
887
+ declare function deriveAcceptanceAuthority(measurability: Measurability, confidence: Confidence): Authority;
888
+
889
+ /** A single advisory finding. `.strict()` rejects unexpected keys. */
890
+ declare const findingSchema: z.ZodObject<{
891
+ target: z.ZodString;
892
+ message: z.ZodString;
893
+ }, "strict", z.ZodTypeAny, {
894
+ message: string;
895
+ target: string;
896
+ }, {
897
+ message: string;
898
+ target: string;
899
+ }>;
900
+ /**
901
+ * Zod schema for the LLM verdict response.
902
+ *
903
+ * `authority` is intentionally ABSENT: it is derived in TypeScript by
904
+ * `deriveAcceptanceAuthority` and must never be supplied by the model. The
905
+ * schema is `.strict()`, so an injected `authority` (or any other extra key)
906
+ * is rejected at the parse boundary rather than silently passing through.
907
+ */
908
+ declare const acceptanceVerdictSchema: z.ZodObject<{
909
+ measurability: z.ZodEnum<["MEASURABLE", "NOT_MEASURABLE", "INCONCLUSIVE"]>;
910
+ confidence: z.ZodEnum<["low", "medium", "high"]>;
911
+ rationale: z.ZodString;
912
+ criteriaFindings: z.ZodArray<z.ZodObject<{
913
+ target: z.ZodString;
914
+ message: z.ZodString;
915
+ }, "strict", z.ZodTypeAny, {
916
+ message: string;
917
+ target: string;
918
+ }, {
919
+ message: string;
920
+ target: string;
921
+ }>, "many">;
922
+ coverageFindings: z.ZodArray<z.ZodObject<{
923
+ target: z.ZodString;
924
+ message: z.ZodString;
925
+ }, "strict", z.ZodTypeAny, {
926
+ message: string;
927
+ target: string;
928
+ }, {
929
+ message: string;
930
+ target: string;
931
+ }>, "many">;
932
+ }, "strict", z.ZodTypeAny, {
933
+ confidence: "low" | "medium" | "high";
934
+ rationale: string;
935
+ measurability: "INCONCLUSIVE" | "MEASURABLE" | "NOT_MEASURABLE";
936
+ criteriaFindings: {
937
+ message: string;
938
+ target: string;
939
+ }[];
940
+ coverageFindings: {
941
+ message: string;
942
+ target: string;
943
+ }[];
944
+ }, {
945
+ confidence: "low" | "medium" | "high";
946
+ rationale: string;
947
+ measurability: "INCONCLUSIVE" | "MEASURABLE" | "NOT_MEASURABLE";
948
+ criteriaFindings: {
949
+ message: string;
950
+ target: string;
951
+ }[];
952
+ coverageFindings: {
953
+ message: string;
954
+ target: string;
955
+ }[];
956
+ }>;
957
+ type LlmAcceptanceVerdict = z.infer<typeof acceptanceVerdictSchema>;
958
+ /**
959
+ * System prompt for acceptance-eval. Conservative-confidence posture mirrors
960
+ * outcome-eval: default to medium; high requires naming a specific criterion;
961
+ * bias toward advisory. `authority` is derived in TypeScript and must never be
962
+ * supplied by the model — the schema is `.strict()` and rejects it.
963
+ */
964
+ declare const ACCEPTANCE_EVAL_SYSTEM_PROMPT = "You are a PRE-execution acceptance-criteria judge. Given a spec acceptance section (and optionally located test snippets), assess three things:\n(a) criteria quality \u2014 are the success criteria observable, testable, and complete? (advisory findings)\n(b) coverage \u2014 do any user-visible behaviors lack a covering test? (advisory findings)\n(c) measurability \u2014 does the spec state MEASURABLE, NOT_MEASURABLE, or is it INCONCLUSIVE on whether any measurable success criteria exist at all?\n\nConfidence calibration (be conservative \u2014 false alarms are costly):\n- Default to \"medium\" confidence.\n- Use \"high\" ONLY when you can name a SPECIFIC criterion (or its absence) and quote or paraphrase it in the rationale.\n- Use \"low\" when the section is ambiguous, partial, or insufficient to judge.\n- Bias toward advisory caution: if unsure between two confidence levels, choose the lower one.\n\nRules:\n- \"measurability\" is NOT_MEASURABLE only when the section states no observable, testable success criterion at all.\n- \"criteriaFindings\" holds advisory (a) observations; \"coverageFindings\" holds advisory (b) observations; both may be empty.\n- Do NOT emit an \"authority\" field. Authority is computed downstream in TypeScript from (measurability, confidence) and must never come from you.\n\nReturn your judgment using the structured_output tool.";
965
+ /**
966
+ * Build the user prompt from the resolved spec section body and optional
967
+ * located test snippets. Test content is clamped to PROMPT_FIELD_MAX_CHARS and
968
+ * wrapped in a 4-backtick fence so an inner ``` cannot close the fence early.
969
+ */
970
+ declare function buildUserPrompt(section: string, testContent?: string): string;
971
+
972
+ interface AcceptanceEvaluatorOptions {
973
+ /** Override model for the acceptance-eval LLM call. */
974
+ model?: string;
975
+ }
976
+ /**
977
+ * Pre-execution acceptance-criteria judge — the upstream twin of
978
+ * OutcomeEvaluator. Built on the cli AnalysisProvider. The LLM returns only
979
+ * measurability/confidence/criteriaFindings/coverageFindings/rationale;
980
+ * `authority` is derived in TypeScript and never read from the model.
981
+ *
982
+ * Unlike OutcomeEvaluator it holds no GraphStore: there is no acceptance
983
+ * outcome node type and Phase 1 does not persist (see plan D-P1-3).
984
+ */
985
+ declare class AcceptanceEvaluator {
986
+ private readonly provider;
987
+ private readonly options;
988
+ constructor(provider: AnalysisProvider, options?: AcceptanceEvaluatorOptions);
989
+ evaluate(input: AcceptanceEvalInput): Promise<AcceptanceVerdict>;
990
+ private judge;
991
+ private degradedVerdict;
992
+ private resolveJudgmentSection;
993
+ private buildVerdict;
994
+ }
995
+
831
996
  /**
832
997
  * Compute historical complexity from past execution outcomes in the graph.
833
998
  *
@@ -1168,4 +1333,4 @@ declare function saveProfiles(projectRoot: string, store: ProfileStore): void;
1168
1333
  */
1169
1334
  declare function refreshProfiles(projectRoot: string, graphStore: GraphStore, opts?: Omit<SpecializationOptions, 'persona'>): ProfileStore;
1170
1335
 
1171
- export { 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, ClaudeCliAnalysisProvider, type ComplexityScore, type Confidence, type EnrichedSpec, type ExecutionOutcome, ExecutionOutcomeConnector, type ExpertiseLevel, type FrameworkRecommendation, type GitHubIssue, GraphValidator, IntelligencePipeline, type JiraIssue, type JudgedAgainst, type LinearIssue, type LlmVerdict, type ManualInput, OUTCOME_EVAL_SYSTEM_PROMPT, OpenAICompatibleAnalysisProvider, type OutcomeEvalInput, OutcomeEvaluator, type OutcomeEvaluatorOptions, type OutcomeIngestResult, type OutcomeVerdict, type PersonaEffectivenessScore, type PersonaRecommendation, PeslSimulator, type PreprocessResult, type ProfileStore, type RawWorkItem, type ResolvedSection, type SimulationResult, type SpecializationEntry, type SpecializationProfile, type SpecializationScore, type TaskType, type TemporalConfig, type Verdict, type WeightedRecommendation, buildSpecializationProfile, buildUserPrompt, computeExpertiseLevel, computeHistoricalComplexity, computePersonaEffectiveness, computeSemanticComplexity, computeSpecialization, computeStructuralComplexity, createCanaryAdapter, decayWeight, deriveAuthority, detectBlindSpots, enrich, githubToRawWorkItem, jiraToRawWorkItem, linearToRawWorkItem, loadProfiles, manualToRawWorkItem, recommendPersona, refreshProfiles, resolveSection, runGraphOnlyChecks, runLlmSimulation, saveProfiles, score as scoreCML, scoreToConcernSignals, temporalSuccessRate, toRawWorkItem, verdictSchema, weightedRecommendPersona };
1336
+ 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, ClaudeCliAnalysisProvider, type ComplexityScore, type Confidence, 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 PreprocessResult, type ProfileStore, type RawWorkItem, type ResolvedSection, type SimulationResult, type SpecializationEntry, type SpecializationProfile, type SpecializationScore, type TaskType, type TemporalConfig, type Verdict, type WeightedRecommendation, acceptanceVerdictSchema, buildUserPrompt as buildAcceptanceUserPrompt, buildSpecializationProfile, buildUserPrompt$1 as buildUserPrompt, computeExpertiseLevel, computeHistoricalComplexity, computePersonaEffectiveness, computeSemanticComplexity, computeSpecialization, computeStructuralComplexity, createCanaryAdapter, decayWeight, deriveAcceptanceAuthority, deriveAuthority, detectBlindSpots, enrich, findingSchema, githubToRawWorkItem, jiraToRawWorkItem, linearToRawWorkItem, loadProfiles, manualToRawWorkItem, recommendPersona, refreshProfiles, resolveSection, runGraphOnlyChecks, runLlmSimulation, saveProfiles, score as scoreCML, scoreToConcernSignals, temporalSuccessRate, toRawWorkItem, verdictSchema, weightedRecommendPersona };
package/dist/index.js CHANGED
@@ -30,6 +30,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ ACCEPTANCE_EVAL_SYSTEM_PROMPT: () => ACCEPTANCE_EVAL_SYSTEM_PROMPT,
34
+ AcceptanceEvaluator: () => AcceptanceEvaluator,
33
35
  AnthropicAnalysisProvider: () => AnthropicAnalysisProvider,
34
36
  ClaudeCliAnalysisProvider: () => ClaudeCliAnalysisProvider,
35
37
  ExecutionOutcomeConnector: () => ExecutionOutcomeConnector,
@@ -39,6 +41,8 @@ __export(index_exports, {
39
41
  OpenAICompatibleAnalysisProvider: () => OpenAICompatibleAnalysisProvider,
40
42
  OutcomeEvaluator: () => OutcomeEvaluator,
41
43
  PeslSimulator: () => PeslSimulator,
44
+ acceptanceVerdictSchema: () => acceptanceVerdictSchema,
45
+ buildAcceptanceUserPrompt: () => buildUserPrompt3,
42
46
  buildSpecializationProfile: () => buildSpecializationProfile,
43
47
  buildUserPrompt: () => buildUserPrompt2,
44
48
  computeExpertiseLevel: () => computeExpertiseLevel,
@@ -49,9 +53,11 @@ __export(index_exports, {
49
53
  computeStructuralComplexity: () => computeStructuralComplexity,
50
54
  createCanaryAdapter: () => createCanaryAdapter,
51
55
  decayWeight: () => decayWeight,
56
+ deriveAcceptanceAuthority: () => deriveAcceptanceAuthority,
52
57
  deriveAuthority: () => deriveAuthority,
53
58
  detectBlindSpots: () => detectBlindSpots,
54
59
  enrich: () => enrich,
60
+ findingSchema: () => findingSchema,
55
61
  githubToRawWorkItem: () => githubToRawWorkItem,
56
62
  jiraToRawWorkItem: () => jiraToRawWorkItem,
57
63
  linearToRawWorkItem: () => linearToRawWorkItem,
@@ -1497,6 +1503,145 @@ var OutcomeEvaluator = class {
1497
1503
  }
1498
1504
  };
1499
1505
 
1506
+ // src/acceptance-eval/authority.ts
1507
+ function deriveAcceptanceAuthority(measurability, confidence) {
1508
+ return measurability === "NOT_MEASURABLE" && confidence === "high" ? "blocking" : "advisory";
1509
+ }
1510
+
1511
+ // src/acceptance-eval/prompts.ts
1512
+ var import_zod5 = require("zod");
1513
+ var findingSchema = import_zod5.z.object({
1514
+ target: import_zod5.z.string().describe("The criterion or user-visible behavior referenced"),
1515
+ message: import_zod5.z.string().describe("The advisory observation")
1516
+ }).strict();
1517
+ var acceptanceVerdictSchema = import_zod5.z.object({
1518
+ measurability: import_zod5.z.enum(["MEASURABLE", "NOT_MEASURABLE", "INCONCLUSIVE"]).describe("Whether the spec section states measurable, testable success criteria"),
1519
+ confidence: import_zod5.z.enum(["low", "medium", "high"]).describe("Confidence in the verdict; high requires a named criterion"),
1520
+ rationale: import_zod5.z.string().describe("Cites specific criteria/behaviors"),
1521
+ criteriaFindings: import_zod5.z.array(findingSchema).describe("(a) advisory observability/testability/completeness critique"),
1522
+ coverageFindings: import_zod5.z.array(findingSchema).describe("(b) advisory user-visible behaviors with no covering test")
1523
+ }).strict();
1524
+ var ACCEPTANCE_EVAL_SYSTEM_PROMPT = `You are a PRE-execution acceptance-criteria judge. Given a spec acceptance section (and optionally located test snippets), assess three things:
1525
+ (a) criteria quality \u2014 are the success criteria observable, testable, and complete? (advisory findings)
1526
+ (b) coverage \u2014 do any user-visible behaviors lack a covering test? (advisory findings)
1527
+ (c) measurability \u2014 does the spec state MEASURABLE, NOT_MEASURABLE, or is it INCONCLUSIVE on whether any measurable success criteria exist at all?
1528
+
1529
+ Confidence calibration (be conservative \u2014 false alarms are costly):
1530
+ - Default to "medium" confidence.
1531
+ - Use "high" ONLY when you can name a SPECIFIC criterion (or its absence) and quote or paraphrase it in the rationale.
1532
+ - Use "low" when the section is ambiguous, partial, or insufficient to judge.
1533
+ - Bias toward advisory caution: if unsure between two confidence levels, choose the lower one.
1534
+
1535
+ Rules:
1536
+ - "measurability" is NOT_MEASURABLE only when the section states no observable, testable success criterion at all.
1537
+ - "criteriaFindings" holds advisory (a) observations; "coverageFindings" holds advisory (b) observations; both may be empty.
1538
+ - Do NOT emit an "authority" field. Authority is computed downstream in TypeScript from (measurability, confidence) and must never come from you.
1539
+
1540
+ Return your judgment using the structured_output tool.`;
1541
+ var PROMPT_FIELD_MAX_CHARS2 = 12e3;
1542
+ var FENCE2 = "````";
1543
+ function clampField2(text) {
1544
+ const trimmed = text.trim();
1545
+ if (trimmed.length <= PROMPT_FIELD_MAX_CHARS2) return trimmed;
1546
+ const dropped = trimmed.length - PROMPT_FIELD_MAX_CHARS2;
1547
+ return `${trimmed.slice(0, PROMPT_FIELD_MAX_CHARS2)}
1548
+ \u2026 [truncated ${dropped} chars]`;
1549
+ }
1550
+ function buildUserPrompt3(section, testContent) {
1551
+ const tests = (testContent ?? "").trim();
1552
+ return [
1553
+ "## Spec Acceptance Criteria (judge against this section)",
1554
+ section.trim() || "(empty \u2014 treat as inconclusive)",
1555
+ "",
1556
+ "## Located Test Snippets (coverage evidence \u2014 may be absent)",
1557
+ `${FENCE2}`,
1558
+ tests ? clampField2(tests) : "(no test content provided)",
1559
+ FENCE2,
1560
+ "",
1561
+ "## Instructions",
1562
+ "Judge measurability (c), and emit advisory criteria (a) and coverage (b) findings. Calibrate confidence conservatively per your system instructions. Cite specific criteria in the rationale."
1563
+ ].join("\n");
1564
+ }
1565
+
1566
+ // src/acceptance-eval/evaluator.ts
1567
+ var import_promises2 = require("fs/promises");
1568
+ var AcceptanceEvaluator = class {
1569
+ provider;
1570
+ options;
1571
+ constructor(provider, options = {}) {
1572
+ this.provider = provider;
1573
+ this.options = options;
1574
+ }
1575
+ async evaluate(input) {
1576
+ let resolved;
1577
+ try {
1578
+ resolved = await this.resolveJudgmentSection(input);
1579
+ } catch {
1580
+ return this.degradedVerdict("overview");
1581
+ }
1582
+ if (resolved === null) {
1583
+ return this.buildVerdict(
1584
+ "INCONCLUSIVE",
1585
+ "low",
1586
+ "No judgable spec section found.",
1587
+ "overview",
1588
+ [],
1589
+ []
1590
+ );
1591
+ }
1592
+ return this.judge(resolved, input);
1593
+ }
1594
+ async judge(resolved, input) {
1595
+ try {
1596
+ const response = await this.provider.analyze({
1597
+ prompt: buildUserPrompt3(resolved.body, input.testContent),
1598
+ systemPrompt: ACCEPTANCE_EVAL_SYSTEM_PROMPT,
1599
+ responseSchema: acceptanceVerdictSchema,
1600
+ ...this.options.model !== void 0 && { model: this.options.model }
1601
+ });
1602
+ const llm = acceptanceVerdictSchema.parse(response.result);
1603
+ return this.buildVerdict(
1604
+ llm.measurability,
1605
+ llm.confidence,
1606
+ llm.rationale,
1607
+ resolved.judgedAgainst,
1608
+ llm.criteriaFindings,
1609
+ llm.coverageFindings
1610
+ );
1611
+ } catch {
1612
+ return this.degradedVerdict(resolved.judgedAgainst);
1613
+ }
1614
+ }
1615
+ degradedVerdict(judgedAgainst) {
1616
+ return this.buildVerdict(
1617
+ "INCONCLUSIVE",
1618
+ "low",
1619
+ "Evaluation could not be completed; defaulting to an inconclusive, advisory verdict.",
1620
+ judgedAgainst,
1621
+ [],
1622
+ []
1623
+ );
1624
+ }
1625
+ async resolveJudgmentSection(input) {
1626
+ if (input.specSection !== void 0) {
1627
+ return input.specSection.trim() === "" ? null : { judgedAgainst: "success-criteria", body: input.specSection };
1628
+ }
1629
+ const markdown = await (0, import_promises2.readFile)(input.specPath, "utf8");
1630
+ return resolveSection(markdown);
1631
+ }
1632
+ buildVerdict(measurability, confidence, rationale, judgedAgainst, criteriaFindings, coverageFindings) {
1633
+ return {
1634
+ measurability,
1635
+ confidence,
1636
+ rationale,
1637
+ judgedAgainst,
1638
+ criteriaFindings,
1639
+ coverageFindings,
1640
+ authority: deriveAcceptanceAuthority(measurability, confidence)
1641
+ };
1642
+ }
1643
+ };
1644
+
1500
1645
  // src/pipeline.ts
1501
1646
  var IntelligencePipeline = class {
1502
1647
  provider;
@@ -1969,6 +2114,8 @@ function refreshProfiles(projectRoot, graphStore, opts) {
1969
2114
  }
1970
2115
  // Annotate the CommonJS export names for ESM import in node:
1971
2116
  0 && (module.exports = {
2117
+ ACCEPTANCE_EVAL_SYSTEM_PROMPT,
2118
+ AcceptanceEvaluator,
1972
2119
  AnthropicAnalysisProvider,
1973
2120
  ClaudeCliAnalysisProvider,
1974
2121
  ExecutionOutcomeConnector,
@@ -1978,6 +2125,8 @@ function refreshProfiles(projectRoot, graphStore, opts) {
1978
2125
  OpenAICompatibleAnalysisProvider,
1979
2126
  OutcomeEvaluator,
1980
2127
  PeslSimulator,
2128
+ acceptanceVerdictSchema,
2129
+ buildAcceptanceUserPrompt,
1981
2130
  buildSpecializationProfile,
1982
2131
  buildUserPrompt,
1983
2132
  computeExpertiseLevel,
@@ -1988,9 +2137,11 @@ function refreshProfiles(projectRoot, graphStore, opts) {
1988
2137
  computeStructuralComplexity,
1989
2138
  createCanaryAdapter,
1990
2139
  decayWeight,
2140
+ deriveAcceptanceAuthority,
1991
2141
  deriveAuthority,
1992
2142
  detectBlindSpots,
1993
2143
  enrich,
2144
+ findingSchema,
1994
2145
  githubToRawWorkItem,
1995
2146
  jiraToRawWorkItem,
1996
2147
  linearToRawWorkItem,
package/dist/index.mjs CHANGED
@@ -1423,6 +1423,145 @@ var OutcomeEvaluator = class {
1423
1423
  }
1424
1424
  };
1425
1425
 
1426
+ // src/acceptance-eval/authority.ts
1427
+ function deriveAcceptanceAuthority(measurability, confidence) {
1428
+ return measurability === "NOT_MEASURABLE" && confidence === "high" ? "blocking" : "advisory";
1429
+ }
1430
+
1431
+ // src/acceptance-eval/prompts.ts
1432
+ import { z as z5 } from "zod";
1433
+ var findingSchema = z5.object({
1434
+ target: z5.string().describe("The criterion or user-visible behavior referenced"),
1435
+ message: z5.string().describe("The advisory observation")
1436
+ }).strict();
1437
+ var acceptanceVerdictSchema = z5.object({
1438
+ measurability: z5.enum(["MEASURABLE", "NOT_MEASURABLE", "INCONCLUSIVE"]).describe("Whether the spec section states measurable, testable success criteria"),
1439
+ confidence: z5.enum(["low", "medium", "high"]).describe("Confidence in the verdict; high requires a named criterion"),
1440
+ rationale: z5.string().describe("Cites specific criteria/behaviors"),
1441
+ criteriaFindings: z5.array(findingSchema).describe("(a) advisory observability/testability/completeness critique"),
1442
+ coverageFindings: z5.array(findingSchema).describe("(b) advisory user-visible behaviors with no covering test")
1443
+ }).strict();
1444
+ var ACCEPTANCE_EVAL_SYSTEM_PROMPT = `You are a PRE-execution acceptance-criteria judge. Given a spec acceptance section (and optionally located test snippets), assess three things:
1445
+ (a) criteria quality \u2014 are the success criteria observable, testable, and complete? (advisory findings)
1446
+ (b) coverage \u2014 do any user-visible behaviors lack a covering test? (advisory findings)
1447
+ (c) measurability \u2014 does the spec state MEASURABLE, NOT_MEASURABLE, or is it INCONCLUSIVE on whether any measurable success criteria exist at all?
1448
+
1449
+ Confidence calibration (be conservative \u2014 false alarms are costly):
1450
+ - Default to "medium" confidence.
1451
+ - Use "high" ONLY when you can name a SPECIFIC criterion (or its absence) and quote or paraphrase it in the rationale.
1452
+ - Use "low" when the section is ambiguous, partial, or insufficient to judge.
1453
+ - Bias toward advisory caution: if unsure between two confidence levels, choose the lower one.
1454
+
1455
+ Rules:
1456
+ - "measurability" is NOT_MEASURABLE only when the section states no observable, testable success criterion at all.
1457
+ - "criteriaFindings" holds advisory (a) observations; "coverageFindings" holds advisory (b) observations; both may be empty.
1458
+ - Do NOT emit an "authority" field. Authority is computed downstream in TypeScript from (measurability, confidence) and must never come from you.
1459
+
1460
+ Return your judgment using the structured_output tool.`;
1461
+ var PROMPT_FIELD_MAX_CHARS2 = 12e3;
1462
+ var FENCE2 = "````";
1463
+ function clampField2(text) {
1464
+ const trimmed = text.trim();
1465
+ if (trimmed.length <= PROMPT_FIELD_MAX_CHARS2) return trimmed;
1466
+ const dropped = trimmed.length - PROMPT_FIELD_MAX_CHARS2;
1467
+ return `${trimmed.slice(0, PROMPT_FIELD_MAX_CHARS2)}
1468
+ \u2026 [truncated ${dropped} chars]`;
1469
+ }
1470
+ function buildUserPrompt3(section, testContent) {
1471
+ const tests = (testContent ?? "").trim();
1472
+ return [
1473
+ "## Spec Acceptance Criteria (judge against this section)",
1474
+ section.trim() || "(empty \u2014 treat as inconclusive)",
1475
+ "",
1476
+ "## Located Test Snippets (coverage evidence \u2014 may be absent)",
1477
+ `${FENCE2}`,
1478
+ tests ? clampField2(tests) : "(no test content provided)",
1479
+ FENCE2,
1480
+ "",
1481
+ "## Instructions",
1482
+ "Judge measurability (c), and emit advisory criteria (a) and coverage (b) findings. Calibrate confidence conservatively per your system instructions. Cite specific criteria in the rationale."
1483
+ ].join("\n");
1484
+ }
1485
+
1486
+ // src/acceptance-eval/evaluator.ts
1487
+ import { readFile as readFile2 } from "fs/promises";
1488
+ var AcceptanceEvaluator = class {
1489
+ provider;
1490
+ options;
1491
+ constructor(provider, options = {}) {
1492
+ this.provider = provider;
1493
+ this.options = options;
1494
+ }
1495
+ async evaluate(input) {
1496
+ let resolved;
1497
+ try {
1498
+ resolved = await this.resolveJudgmentSection(input);
1499
+ } catch {
1500
+ return this.degradedVerdict("overview");
1501
+ }
1502
+ if (resolved === null) {
1503
+ return this.buildVerdict(
1504
+ "INCONCLUSIVE",
1505
+ "low",
1506
+ "No judgable spec section found.",
1507
+ "overview",
1508
+ [],
1509
+ []
1510
+ );
1511
+ }
1512
+ return this.judge(resolved, input);
1513
+ }
1514
+ async judge(resolved, input) {
1515
+ try {
1516
+ const response = await this.provider.analyze({
1517
+ prompt: buildUserPrompt3(resolved.body, input.testContent),
1518
+ systemPrompt: ACCEPTANCE_EVAL_SYSTEM_PROMPT,
1519
+ responseSchema: acceptanceVerdictSchema,
1520
+ ...this.options.model !== void 0 && { model: this.options.model }
1521
+ });
1522
+ const llm = acceptanceVerdictSchema.parse(response.result);
1523
+ return this.buildVerdict(
1524
+ llm.measurability,
1525
+ llm.confidence,
1526
+ llm.rationale,
1527
+ resolved.judgedAgainst,
1528
+ llm.criteriaFindings,
1529
+ llm.coverageFindings
1530
+ );
1531
+ } catch {
1532
+ return this.degradedVerdict(resolved.judgedAgainst);
1533
+ }
1534
+ }
1535
+ degradedVerdict(judgedAgainst) {
1536
+ return this.buildVerdict(
1537
+ "INCONCLUSIVE",
1538
+ "low",
1539
+ "Evaluation could not be completed; defaulting to an inconclusive, advisory verdict.",
1540
+ judgedAgainst,
1541
+ [],
1542
+ []
1543
+ );
1544
+ }
1545
+ async resolveJudgmentSection(input) {
1546
+ if (input.specSection !== void 0) {
1547
+ return input.specSection.trim() === "" ? null : { judgedAgainst: "success-criteria", body: input.specSection };
1548
+ }
1549
+ const markdown = await readFile2(input.specPath, "utf8");
1550
+ return resolveSection(markdown);
1551
+ }
1552
+ buildVerdict(measurability, confidence, rationale, judgedAgainst, criteriaFindings, coverageFindings) {
1553
+ return {
1554
+ measurability,
1555
+ confidence,
1556
+ rationale,
1557
+ judgedAgainst,
1558
+ criteriaFindings,
1559
+ coverageFindings,
1560
+ authority: deriveAcceptanceAuthority(measurability, confidence)
1561
+ };
1562
+ }
1563
+ };
1564
+
1426
1565
  // src/pipeline.ts
1427
1566
  var IntelligencePipeline = class {
1428
1567
  provider;
@@ -1894,6 +2033,8 @@ function refreshProfiles(projectRoot, graphStore, opts) {
1894
2033
  return store;
1895
2034
  }
1896
2035
  export {
2036
+ ACCEPTANCE_EVAL_SYSTEM_PROMPT,
2037
+ AcceptanceEvaluator,
1897
2038
  AnthropicAnalysisProvider,
1898
2039
  ClaudeCliAnalysisProvider,
1899
2040
  ExecutionOutcomeConnector,
@@ -1903,6 +2044,8 @@ export {
1903
2044
  OpenAICompatibleAnalysisProvider,
1904
2045
  OutcomeEvaluator,
1905
2046
  PeslSimulator,
2047
+ acceptanceVerdictSchema,
2048
+ buildUserPrompt3 as buildAcceptanceUserPrompt,
1906
2049
  buildSpecializationProfile,
1907
2050
  buildUserPrompt2 as buildUserPrompt,
1908
2051
  computeExpertiseLevel,
@@ -1913,9 +2056,11 @@ export {
1913
2056
  computeStructuralComplexity,
1914
2057
  createCanaryAdapter,
1915
2058
  decayWeight,
2059
+ deriveAcceptanceAuthority,
1916
2060
  deriveAuthority,
1917
2061
  detectBlindSpots,
1918
2062
  enrich,
2063
+ findingSchema,
1919
2064
  githubToRawWorkItem,
1920
2065
  jiraToRawWorkItem,
1921
2066
  linearToRawWorkItem,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@harness-engineering/intelligence",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Intelligence pipeline for spec enrichment, complexity modeling, and pre-execution simulation",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -40,8 +40,8 @@
40
40
  "@anthropic-ai/sdk": "^0.95.1",
41
41
  "openai": "^6.0.0",
42
42
  "zod": "^3.25.76",
43
- "@harness-engineering/graph": "0.11.0",
44
- "@harness-engineering/types": "0.16.0"
43
+ "@harness-engineering/graph": "0.11.2",
44
+ "@harness-engineering/types": "0.16.2"
45
45
  },
46
46
  "optionalDependencies": {
47
47
  "canary-test-cli": "^5.4.0"