@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 +167 -2
- package/dist/index.d.ts +167 -2
- package/dist/index.js +151 -0
- package/dist/index.mjs +145 -0
- package/package.json +3 -3
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
|
+
"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.
|
|
44
|
-
"@harness-engineering/types": "0.16.
|
|
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"
|