@oscharko-dev/keiko-workflows 0.2.6 → 0.2.7

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.
Files changed (53) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/context-budget/allocator.d.ts +29 -0
  3. package/dist/context-budget/allocator.d.ts.map +1 -0
  4. package/dist/context-budget/allocator.js +185 -0
  5. package/dist/context-budget/compaction-helpers.d.ts +44 -0
  6. package/dist/context-budget/compaction-helpers.d.ts.map +1 -0
  7. package/dist/context-budget/compaction-helpers.js +203 -0
  8. package/dist/context-budget/compaction.d.ts +14 -0
  9. package/dist/context-budget/compaction.d.ts.map +1 -0
  10. package/dist/context-budget/compaction.js +97 -0
  11. package/dist/context-budget/defaults.d.ts +3 -0
  12. package/dist/context-budget/defaults.d.ts.map +1 -0
  13. package/dist/context-budget/defaults.js +75 -0
  14. package/dist/context-budget/index.d.ts +8 -0
  15. package/dist/context-budget/index.d.ts.map +1 -0
  16. package/dist/context-budget/index.js +6 -0
  17. package/dist/context-budget/rehydration.d.ts +11 -0
  18. package/dist/context-budget/rehydration.d.ts.map +1 -0
  19. package/dist/context-budget/rehydration.js +76 -0
  20. package/dist/contextpack/assemble.d.ts +2 -1
  21. package/dist/contextpack/assemble.d.ts.map +1 -1
  22. package/dist/contextpack/assemble.js +19 -0
  23. package/dist/index.d.ts +2 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +4 -0
  26. package/dist/observations/command.d.ts +6 -0
  27. package/dist/observations/command.d.ts.map +1 -0
  28. package/dist/observations/command.js +67 -0
  29. package/dist/observations/index.d.ts +5 -0
  30. package/dist/observations/index.d.ts.map +1 -0
  31. package/dist/observations/index.js +6 -0
  32. package/dist/observations/search.d.ts +9 -0
  33. package/dist/observations/search.d.ts.map +1 -0
  34. package/dist/observations/search.js +43 -0
  35. package/dist/observations/shared.d.ts +18 -0
  36. package/dist/observations/shared.d.ts.map +1 -0
  37. package/dist/observations/shared.js +63 -0
  38. package/dist/observations/test.d.ts +6 -0
  39. package/dist/observations/test.d.ts.map +1 -0
  40. package/dist/observations/test.js +47 -0
  41. package/dist/planner/anchors.d.ts.map +1 -1
  42. package/dist/planner/anchors.js +3 -1
  43. package/dist/planner/intent.d.ts.map +1 -1
  44. package/dist/planner/intent.js +6 -0
  45. package/dist/ranking/rank.d.ts.map +1 -1
  46. package/dist/ranking/rank.js +5 -3
  47. package/dist/ranking/scoring.d.ts +4 -0
  48. package/dist/ranking/scoring.d.ts.map +1 -1
  49. package/dist/ranking/scoring.js +29 -1
  50. package/dist/ranking/signals.d.ts +5 -1
  51. package/dist/ranking/signals.d.ts.map +1 -1
  52. package/dist/ranking/signals.js +23 -3
  53. package/package.json +10 -10
@@ -1 +1 @@
1
- {"version":3,"file":"scoring.d.ts","sourceRoot":"","sources":["../../src/ranking/scoring.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,uBAAuB,EAAE,MAAM,CAAC;IACzC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AAED,eAAO,MAAM,uBAAuB,EAAE,cAQ5B,CAAC;AAgBX,wBAAgB,YAAY,CAC1B,OAAO,EAAE,gBAAgB,EACzB,OAAO,GAAE,cAAwC,GAChD,MAAM,CAUR"}
1
+ {"version":3,"file":"scoring.d.ts","sourceRoot":"","sources":["../../src/ranking/scoring.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,uBAAuB,EAAE,MAAM,CAAC;IACzC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAIlC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,eAAO,MAAM,uBAAuB,EAAE,cAQ5B,CAAC;AAcX,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEnE;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,CAS3E;AAkBD,wBAAgB,YAAY,CAC1B,OAAO,EAAE,gBAAgB,EACzB,OAAO,GAAE,cAAwC,GAChD,MAAM,CAcR"}
@@ -14,6 +14,28 @@ export const DEFAULT_SCORING_WEIGHTS = {
14
14
  stacktracePositionBonus: 0.05,
15
15
  generatedPenalty: 0.3,
16
16
  };
17
+ // Intent-conditioned weight overrides (M4). Only the named intents receive non-default weights for
18
+ // the new canonical-metadata / structural-edge signals; every other intent (and the no-intent
19
+ // default path) returns DEFAULT_SCORING_WEIGHTS verbatim, so ranking is byte-identical there.
20
+ // Weights are deliberately modest (tie-breaker magnitude) to nudge, not dominate, the established
21
+ // provenance/anchor signals.
22
+ const INTENT_BOOSTED = new Set([
23
+ "project-metadata",
24
+ "repository-overview",
25
+ "targeted-code-search",
26
+ "diagnostic-search",
27
+ ]);
28
+ export function isIntentBoosted(intent) {
29
+ return intent !== undefined && INTENT_BOOSTED.has(intent);
30
+ }
31
+ export function weightsForIntent(intent) {
32
+ if (intent === undefined || !INTENT_BOOSTED.has(intent)) {
33
+ return DEFAULT_SCORING_WEIGHTS;
34
+ }
35
+ const canonicalMetadata = intent === "project-metadata" || intent === "repository-overview" ? 0.25 : 0.1;
36
+ const structuralEdge = intent === "targeted-code-search" || intent === "diagnostic-search" ? 0.2 : 0.1;
37
+ return { ...DEFAULT_SCORING_WEIGHTS, canonicalMetadata, structuralEdge };
38
+ }
17
39
  const SIGNAL_WEIGHT_KEYS = {
18
40
  "provenance-best-score": "provenanceBestScore",
19
41
  "provenance-count": "provenanceCount",
@@ -22,6 +44,8 @@ const SIGNAL_WEIGHT_KEYS = {
22
44
  "test-pair-bonus": "testPairBonus",
23
45
  "stacktrace-position-bonus": "stacktracePositionBonus",
24
46
  "generated-penalty": "generatedPenalty",
47
+ "canonical-metadata": "canonicalMetadata",
48
+ "structural-edge": "structuralEdge",
25
49
  };
26
50
  function clampUnit(value) {
27
51
  return Math.max(0, Math.min(1, value));
@@ -33,7 +57,11 @@ export function computeScore(signals, weights = DEFAULT_SCORING_WEIGHTS) {
33
57
  if (key === undefined) {
34
58
  continue;
35
59
  }
36
- raw += signal.value * weights[key];
60
+ const weight = weights[key];
61
+ if (weight === undefined) {
62
+ continue;
63
+ }
64
+ raw += signal.value * weight;
37
65
  }
38
66
  return clampUnit(raw);
39
67
  }
@@ -4,6 +4,10 @@ export interface RankingInput {
4
4
  readonly atoms: readonly EvidenceAtom[];
5
5
  readonly anchors: readonly SearchAnchor[];
6
6
  readonly hints?: RankingHints;
7
+ readonly context?: RankingContext;
8
+ }
9
+ export interface RankingContext {
10
+ readonly retrievalIntent?: string | undefined;
7
11
  }
8
12
  export interface RankingHints {
9
13
  readonly generatedPathPatterns?: readonly string[];
@@ -16,5 +20,5 @@ export interface ExtractedSignals {
16
20
  readonly baseScore: number;
17
21
  readonly generatedHint: boolean;
18
22
  }
19
- export declare function extractSignals(atomsForPath: readonly EvidenceAtom[], anchors: readonly SearchAnchor[], hints: Required<RankingHints>): ExtractedSignals;
23
+ export declare function extractSignals(atomsForPath: readonly EvidenceAtom[], anchors: readonly SearchAnchor[], hints: Required<RankingHints>, context?: RankingContext): ExtractedSignals;
20
24
  //# sourceMappingURL=signals.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../../src/ranking/signals.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACb,MAAM,iDAAiD,CAAC;AAEzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,qBAAqB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnD,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpD;AAED,eAAO,MAAM,0BAA0B,EAAE,SAAS,MAAM,EAS9C,CAAC;AAEX,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IAC7C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;CACjC;AAyHD,wBAAgB,cAAc,CAC5B,YAAY,EAAE,SAAS,YAAY,EAAE,EACrC,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,GAC5B,gBAAgB,CAuBlB"}
1
+ {"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../../src/ranking/signals.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACb,MAAM,iDAAiD,CAAC;AAGzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC;IAI9B,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC;CACnC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/C;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,qBAAqB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnD,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpD;AAUD,eAAO,MAAM,0BAA0B,EAAE,SAAS,MAAM,EAS9C,CAAC;AAEX,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IAC7C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;CACjC;AAyHD,wBAAgB,cAAc,CAC5B,YAAY,EAAE,SAAS,YAAY,EAAE,EACrC,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC7B,OAAO,CAAC,EAAE,cAAc,GACvB,gBAAgB,CAmClB"}
@@ -3,6 +3,14 @@
3
3
  // maps weights to signals by NAME (see SIGNAL_WEIGHT_KEYS in scoring.ts), not by position.
4
4
  // Penalties are emitted alongside positive signals so the scorer treats them uniformly;
5
5
  // downstream code interprets values via signal names only.
6
+ import { isCanonicalMetadataFile } from "@oscharko-dev/keiko-workspace";
7
+ import { isIntentBoosted } from "./scoring.js";
8
+ // True when this candidate is reachable via an inbound import edge or a test↔source pairing, derived
9
+ // from atoms already present (the structural ring's provenance tools). No extra IO.
10
+ const STRUCTURAL_TOOLS = new Set(["import-graph", "test-source-pairing"]);
11
+ function hasStructuralEdge(atoms) {
12
+ return atoms.some((atom) => STRUCTURAL_TOOLS.has(atom.provenance.tool));
13
+ }
6
14
  export const DEFAULT_GENERATED_PATTERNS = [
7
15
  "/dist/",
8
16
  "/build/",
@@ -119,7 +127,7 @@ function deriveScopePath(atoms) {
119
127
  const first = atoms[0];
120
128
  return first === undefined ? "" : first.scopePath;
121
129
  }
122
- export function extractSignals(atomsForPath, anchors, hints) {
130
+ export function extractSignals(atomsForPath, anchors, hints, context) {
123
131
  const scopePath = deriveScopePath(atomsForPath);
124
132
  const generatedHint = detectGenerated(scopePath, hints.generatedPathPatterns);
125
133
  const provBest = computeProvenanceBestScore(atomsForPath);
@@ -129,7 +137,7 @@ export function extractSignals(atomsForPath, anchors, hints) {
129
137
  const testBonus = computeTestPairBonus(scopePath, anchors);
130
138
  const stackBonus = computeStacktracePositionBonus(scopePath, anchors);
131
139
  const penalty = generatedHint ? -1 : 0;
132
- const signals = [
140
+ const baseSignals = [
133
141
  { name: "provenance-best-score", value: provBest },
134
142
  { name: "provenance-count", value: provCount },
135
143
  { name: "anchor-overlap", value: overlap },
@@ -138,8 +146,20 @@ export function extractSignals(atomsForPath, anchors, hints) {
138
146
  { name: "stacktrace-position-bonus", value: stackBonus },
139
147
  { name: "generated-penalty", value: penalty },
140
148
  ];
149
+ // M4: only a boosted intent appends the two new signals (and weightsForIntent only weights them
150
+ // for the same intents), so the signal vector — and therefore the pack/cache content — is
151
+ // byte-identical for every other intent and for callers that pass no context.
152
+ if (isIntentBoosted(context?.retrievalIntent)) {
153
+ baseSignals.push({
154
+ name: "canonical-metadata",
155
+ value: isCanonicalMetadataFile(scopePath) ? 1 : 0,
156
+ });
157
+ baseSignals.push({ name: "structural-edge", value: hasStructuralEdge(atomsForPath) ? 1 : 0 });
158
+ }
159
+ // baseScore intentionally stays over the original positive signals (it feeds nothing the new
160
+ // weighted score touches; the filter uses computeScore output, not baseScore).
141
161
  const positives = [provBest, provCount, overlap, depthAff, testBonus, stackBonus];
142
162
  const positiveMean = positives.reduce((acc, n) => acc + n, 0) / positives.length;
143
163
  const baseScore = clampUnit(positiveMean + penalty);
144
- return { scopePath, signals, baseScore, generatedHint };
164
+ return { scopePath, signals: baseSignals, baseScore, generatedHint };
145
165
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oscharko-dev/keiko-workflows",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "description": "Internal workflows package: reviewable developer-assist workflows (unit-test generation, bug investigation), prompts/parsers/guards/report rendering, apply-mode verification gating, and UI descriptors (ADR-0008 + ADR-0009 + ADR-0019). Not published independently.",
@@ -25,14 +25,14 @@
25
25
  "node": ">=22"
26
26
  },
27
27
  "dependencies": {
28
- "@oscharko-dev/keiko-contracts": "0.2.6",
29
- "@oscharko-dev/keiko-security": "0.2.6",
30
- "@oscharko-dev/keiko-model-gateway": "0.2.6",
31
- "@oscharko-dev/keiko-workspace": "0.2.6",
32
- "@oscharko-dev/keiko-tools": "0.2.6",
33
- "@oscharko-dev/keiko-evidence": "0.2.6",
34
- "@oscharko-dev/keiko-verification": "0.2.6",
35
- "@oscharko-dev/keiko-harness": "0.2.6",
36
- "@oscharko-dev/keiko-quality-intelligence": "0.2.6"
28
+ "@oscharko-dev/keiko-contracts": "0.2.7",
29
+ "@oscharko-dev/keiko-security": "0.2.7",
30
+ "@oscharko-dev/keiko-model-gateway": "0.2.7",
31
+ "@oscharko-dev/keiko-workspace": "0.2.7",
32
+ "@oscharko-dev/keiko-tools": "0.2.7",
33
+ "@oscharko-dev/keiko-evidence": "0.2.7",
34
+ "@oscharko-dev/keiko-verification": "0.2.7",
35
+ "@oscharko-dev/keiko-harness": "0.2.7",
36
+ "@oscharko-dev/keiko-quality-intelligence": "0.2.7"
37
37
  }
38
38
  }