@urateam/core 0.1.16 → 0.1.19
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/__tests__/agentic-deep-review-provider.test.d.ts +2 -0
- package/dist/__tests__/agentic-deep-review-provider.test.d.ts.map +1 -0
- package/dist/__tests__/agentic-deep-review-provider.test.js +70 -0
- package/dist/__tests__/agentic-deep-review-provider.test.js.map +1 -0
- package/dist/__tests__/audit-immutability.test.js +16 -1
- package/dist/__tests__/audit-immutability.test.js.map +1 -1
- package/dist/__tests__/cost/per-run-multi-model.test.d.ts +2 -0
- package/dist/__tests__/cost/per-run-multi-model.test.d.ts.map +1 -0
- package/dist/__tests__/cost/per-run-multi-model.test.js +102 -0
- package/dist/__tests__/cost/per-run-multi-model.test.js.map +1 -0
- package/dist/__tests__/db-qa-gap-issues.test.d.ts +2 -0
- package/dist/__tests__/db-qa-gap-issues.test.d.ts.map +1 -0
- package/dist/__tests__/db-qa-gap-issues.test.js +113 -0
- package/dist/__tests__/db-qa-gap-issues.test.js.map +1 -0
- package/dist/__tests__/db-release-decisions.test.d.ts +2 -0
- package/dist/__tests__/db-release-decisions.test.d.ts.map +1 -0
- package/dist/__tests__/db-release-decisions.test.js +98 -0
- package/dist/__tests__/db-release-decisions.test.js.map +1 -0
- package/dist/__tests__/db-review-model-runs.test.d.ts +2 -0
- package/dist/__tests__/db-review-model-runs.test.d.ts.map +1 -0
- package/dist/__tests__/db-review-model-runs.test.js +90 -0
- package/dist/__tests__/db-review-model-runs.test.js.map +1 -0
- package/dist/__tests__/e2e-fanout.test.d.ts +17 -0
- package/dist/__tests__/e2e-fanout.test.d.ts.map +1 -0
- package/dist/__tests__/e2e-fanout.test.js +184 -0
- package/dist/__tests__/e2e-fanout.test.js.map +1 -0
- package/dist/__tests__/e2e-pipeline.test.js +1 -0
- package/dist/__tests__/e2e-pipeline.test.js.map +1 -1
- package/dist/__tests__/notifier-discord.test.js +3 -3
- package/dist/__tests__/notifier-discord.test.js.map +1 -1
- package/dist/__tests__/notifier-slack.test.js +2 -2
- package/dist/__tests__/notifier-slack.test.js.map +1 -1
- package/dist/__tests__/notifier.test.js +1 -0
- package/dist/__tests__/notifier.test.js.map +1 -1
- package/dist/__tests__/openrouter-client.test.d.ts +2 -0
- package/dist/__tests__/openrouter-client.test.d.ts.map +1 -0
- package/dist/__tests__/openrouter-client.test.js +56 -0
- package/dist/__tests__/openrouter-client.test.js.map +1 -0
- package/dist/__tests__/openrouter-fanout.test.d.ts +2 -0
- package/dist/__tests__/openrouter-fanout.test.d.ts.map +1 -0
- package/dist/__tests__/openrouter-fanout.test.js +93 -0
- package/dist/__tests__/openrouter-fanout.test.js.map +1 -0
- package/dist/__tests__/pm-budget.test.js +1 -0
- package/dist/__tests__/pm-budget.test.js.map +1 -1
- package/dist/__tests__/pm-promote.test.js +189 -0
- package/dist/__tests__/pm-promote.test.js.map +1 -1
- package/dist/__tests__/pm-scheduler.test.js +1 -0
- package/dist/__tests__/pm-scheduler.test.js.map +1 -1
- package/dist/__tests__/pm-types.test.js +2 -0
- package/dist/__tests__/pm-types.test.js.map +1 -1
- package/dist/__tests__/post-fanout-comments.test.d.ts +2 -0
- package/dist/__tests__/post-fanout-comments.test.d.ts.map +1 -0
- package/dist/__tests__/post-fanout-comments.test.js +84 -0
- package/dist/__tests__/post-fanout-comments.test.js.map +1 -0
- package/dist/__tests__/qa-audit-events.test.d.ts +2 -0
- package/dist/__tests__/qa-audit-events.test.d.ts.map +1 -0
- package/dist/__tests__/qa-audit-events.test.js +57 -0
- package/dist/__tests__/qa-audit-events.test.js.map +1 -0
- package/dist/__tests__/qa-config.test.d.ts +2 -0
- package/dist/__tests__/qa-config.test.d.ts.map +1 -0
- package/dist/__tests__/qa-config.test.js +80 -0
- package/dist/__tests__/qa-config.test.js.map +1 -0
- package/dist/__tests__/qa-eval.test.d.ts +2 -0
- package/dist/__tests__/qa-eval.test.d.ts.map +1 -0
- package/dist/__tests__/qa-eval.test.js +146 -0
- package/dist/__tests__/qa-eval.test.js.map +1 -0
- package/dist/__tests__/qa-gap.test.d.ts +2 -0
- package/dist/__tests__/qa-gap.test.d.ts.map +1 -0
- package/dist/__tests__/qa-gap.test.js +100 -0
- package/dist/__tests__/qa-gap.test.js.map +1 -0
- package/dist/__tests__/qa-github.test.d.ts +2 -0
- package/dist/__tests__/qa-github.test.d.ts.map +1 -0
- package/dist/__tests__/qa-github.test.js +162 -0
- package/dist/__tests__/qa-github.test.js.map +1 -0
- package/dist/__tests__/ralph-review-fix-regression.test.js +1 -0
- package/dist/__tests__/ralph-review-fix-regression.test.js.map +1 -1
- package/dist/__tests__/release-manager-audit-events.test.d.ts +2 -0
- package/dist/__tests__/release-manager-audit-events.test.d.ts.map +1 -0
- package/dist/__tests__/release-manager-audit-events.test.js +64 -0
- package/dist/__tests__/release-manager-audit-events.test.js.map +1 -0
- package/dist/__tests__/release-manager-config.test.d.ts +2 -0
- package/dist/__tests__/release-manager-config.test.d.ts.map +1 -0
- package/dist/__tests__/release-manager-config.test.js +56 -0
- package/dist/__tests__/release-manager-config.test.js.map +1 -0
- package/dist/__tests__/release-manager-decide.test.d.ts +2 -0
- package/dist/__tests__/release-manager-decide.test.d.ts.map +1 -0
- package/dist/__tests__/release-manager-decide.test.js +102 -0
- package/dist/__tests__/release-manager-decide.test.js.map +1 -0
- package/dist/__tests__/release-manager-github.test.d.ts +2 -0
- package/dist/__tests__/release-manager-github.test.d.ts.map +1 -0
- package/dist/__tests__/release-manager-github.test.js +83 -0
- package/dist/__tests__/release-manager-github.test.js.map +1 -0
- package/dist/__tests__/release-manager-license-gate.test.d.ts +2 -0
- package/dist/__tests__/release-manager-license-gate.test.d.ts.map +1 -0
- package/dist/__tests__/release-manager-license-gate.test.js +25 -0
- package/dist/__tests__/release-manager-license-gate.test.js.map +1 -0
- package/dist/__tests__/release-manager-scheduler.test.d.ts +2 -0
- package/dist/__tests__/release-manager-scheduler.test.d.ts.map +1 -0
- package/dist/__tests__/release-manager-scheduler.test.js +395 -0
- package/dist/__tests__/release-manager-scheduler.test.js.map +1 -0
- package/dist/__tests__/release-manager-slack-handler.test.d.ts +2 -0
- package/dist/__tests__/release-manager-slack-handler.test.d.ts.map +1 -0
- package/dist/__tests__/release-manager-slack-handler.test.js +175 -0
- package/dist/__tests__/release-manager-slack-handler.test.js.map +1 -0
- package/dist/__tests__/release-manager-triggers.test.d.ts +2 -0
- package/dist/__tests__/release-manager-triggers.test.d.ts.map +1 -0
- package/dist/__tests__/release-manager-triggers.test.js +67 -0
- package/dist/__tests__/release-manager-triggers.test.js.map +1 -0
- package/dist/__tests__/release-manager-versioning.test.d.ts +2 -0
- package/dist/__tests__/release-manager-versioning.test.d.ts.map +1 -0
- package/dist/__tests__/release-manager-versioning.test.js +51 -0
- package/dist/__tests__/release-manager-versioning.test.js.map +1 -0
- package/dist/__tests__/reproduce-bec113-pagination-warning.test.js +1 -0
- package/dist/__tests__/reproduce-bec113-pagination-warning.test.js.map +1 -1
- package/dist/__tests__/reproduce-bec62.test.js +1 -0
- package/dist/__tests__/reproduce-bec62.test.js.map +1 -1
- package/dist/__tests__/reproduce-bec91-stuck-in-progress.test.js +2 -0
- package/dist/__tests__/reproduce-bec91-stuck-in-progress.test.js.map +1 -1
- package/dist/__tests__/review-prompt.test.d.ts +2 -0
- package/dist/__tests__/review-prompt.test.d.ts.map +1 -0
- package/dist/__tests__/review-prompt.test.js +88 -0
- package/dist/__tests__/review-prompt.test.js.map +1 -0
- package/dist/__tests__/review-provider-registry.test.d.ts +2 -0
- package/dist/__tests__/review-provider-registry.test.d.ts.map +1 -0
- package/dist/__tests__/review-provider-registry.test.js +61 -0
- package/dist/__tests__/review-provider-registry.test.js.map +1 -0
- package/dist/__tests__/runner-fanout-integration.test.d.ts +2 -0
- package/dist/__tests__/runner-fanout-integration.test.d.ts.map +1 -0
- package/dist/__tests__/runner-fanout-integration.test.js +107 -0
- package/dist/__tests__/runner-fanout-integration.test.js.map +1 -0
- package/dist/__tests__/webhook-handler.test.js +1 -0
- package/dist/__tests__/webhook-handler.test.js.map +1 -1
- package/dist/audit/events.d.ts +54 -0
- package/dist/audit/events.d.ts.map +1 -1
- package/dist/audit/events.js +100 -0
- package/dist/audit/events.js.map +1 -1
- package/dist/audit/writer.d.ts +22 -8
- package/dist/audit/writer.d.ts.map +1 -1
- package/dist/audit/writer.js +22 -8
- package/dist/audit/writer.js.map +1 -1
- package/dist/cost/aggregate.d.ts.map +1 -1
- package/dist/cost/aggregate.js +14 -2
- package/dist/cost/aggregate.js.map +1 -1
- package/dist/cost/csv.d.ts.map +1 -1
- package/dist/cost/csv.js +14 -2
- package/dist/cost/csv.js.map +1 -1
- package/dist/cost/per-run.d.ts +11 -0
- package/dist/cost/per-run.d.ts.map +1 -1
- package/dist/cost/per-run.js +21 -8
- package/dist/cost/per-run.js.map +1 -1
- package/dist/cost/rollup.d.ts.map +1 -1
- package/dist/cost/rollup.js +14 -2
- package/dist/cost/rollup.js.map +1 -1
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +20 -1
- package/dist/db/client.js.map +1 -1
- package/dist/db/migrations/postgres/009_review_model_runs.sql +18 -0
- package/dist/db/migrations/postgres/010_release_manager.sql +38 -0
- package/dist/db/migrations/postgres/011_qa_run_columns.sql +8 -0
- package/dist/db/migrations/postgres/012_qa_gap_issues.sql +18 -0
- package/dist/db/migrations/sqlite/008_review_model_runs.sql +18 -0
- package/dist/db/migrations/sqlite/009_release_manager.sql +43 -0
- package/dist/db/migrations/sqlite/010_qa_run_columns.sql +9 -0
- package/dist/db/migrations/sqlite/011_qa_gap_issues.sql +22 -0
- package/dist/db/review-model-runs.d.ts +4 -0
- package/dist/db/review-model-runs.d.ts.map +1 -0
- package/dist/db/review-model-runs.js +25 -0
- package/dist/db/review-model-runs.js.map +1 -0
- package/dist/db/schema.d.ts +761 -0
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +67 -0
- package/dist/db/schema.js.map +1 -1
- package/dist/executor/executor.d.ts.map +1 -1
- package/dist/executor/executor.js +2 -0
- package/dist/executor/executor.js.map +1 -1
- package/dist/executor/review/agentic-deep-review.d.ts +6 -0
- package/dist/executor/review/agentic-deep-review.d.ts.map +1 -0
- package/dist/executor/review/agentic-deep-review.js +37 -0
- package/dist/executor/review/agentic-deep-review.js.map +1 -0
- package/dist/executor/review/openrouter-client.d.ts +23 -0
- package/dist/executor/review/openrouter-client.d.ts.map +1 -0
- package/dist/executor/review/openrouter-client.js +34 -0
- package/dist/executor/review/openrouter-client.js.map +1 -0
- package/dist/executor/review/openrouter-fanout.d.ts +17 -0
- package/dist/executor/review/openrouter-fanout.d.ts.map +1 -0
- package/dist/executor/review/openrouter-fanout.js +84 -0
- package/dist/executor/review/openrouter-fanout.js.map +1 -0
- package/dist/executor/review/post-fanout-comments.d.ts +4 -0
- package/dist/executor/review/post-fanout-comments.d.ts.map +1 -0
- package/dist/executor/review/post-fanout-comments.js +45 -0
- package/dist/executor/review/post-fanout-comments.js.map +1 -0
- package/dist/executor/review/review-prompt.d.ts +21 -0
- package/dist/executor/review/review-prompt.d.ts.map +1 -0
- package/dist/executor/review/review-prompt.js +130 -0
- package/dist/executor/review/review-prompt.js.map +1 -0
- package/dist/executor/review/review-provider.d.ts +27 -0
- package/dist/executor/review/review-provider.d.ts.map +1 -0
- package/dist/executor/review/review-provider.js +36 -0
- package/dist/executor/review/review-provider.js.map +1 -0
- package/dist/executor/review/workdir-snapshot.d.ts +13 -0
- package/dist/executor/review/workdir-snapshot.d.ts.map +1 -0
- package/dist/executor/review/workdir-snapshot.js +24 -0
- package/dist/executor/review/workdir-snapshot.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/license.d.ts.map +1 -1
- package/dist/license.js +1 -0
- package/dist/license.js.map +1 -1
- package/dist/pipeline/review-providers-runner.d.ts +31 -0
- package/dist/pipeline/review-providers-runner.d.ts.map +1 -0
- package/dist/pipeline/review-providers-runner.js +64 -0
- package/dist/pipeline/review-providers-runner.js.map +1 -0
- package/dist/pipeline/runner.d.ts.map +1 -1
- package/dist/pipeline/runner.js +99 -7
- package/dist/pipeline/runner.js.map +1 -1
- package/dist/pm/actions/promote.d.ts +12 -0
- package/dist/pm/actions/promote.d.ts.map +1 -1
- package/dist/pm/actions/promote.js +27 -2
- package/dist/pm/actions/promote.js.map +1 -1
- package/dist/pm/actions/resolve-approvals.js +3 -3
- package/dist/pm/actions/resolve-approvals.js.map +1 -1
- package/dist/pm/actions/triage.js +2 -2
- package/dist/pm/actions/triage.js.map +1 -1
- package/dist/pm/scheduler.d.ts.map +1 -1
- package/dist/pm/scheduler.js +5 -3
- package/dist/pm/scheduler.js.map +1 -1
- package/dist/pm/slack-interface.d.ts +8 -0
- package/dist/pm/slack-interface.d.ts.map +1 -1
- package/dist/pm/slack-interface.js +20 -3
- package/dist/pm/slack-interface.js.map +1 -1
- package/dist/pm/types.d.ts +1 -0
- package/dist/pm/types.d.ts.map +1 -1
- package/dist/pm/types.js +6 -0
- package/dist/pm/types.js.map +1 -1
- package/dist/qa/gap.d.ts +29 -0
- package/dist/qa/gap.d.ts.map +1 -0
- package/dist/qa/gap.js +91 -0
- package/dist/qa/gap.js.map +1 -0
- package/dist/qa/github.d.ts +77 -0
- package/dist/qa/github.d.ts.map +1 -0
- package/dist/qa/github.js +106 -0
- package/dist/qa/github.js.map +1 -0
- package/dist/qa/index.d.ts +4 -0
- package/dist/qa/index.d.ts.map +1 -0
- package/dist/qa/index.js +4 -0
- package/dist/qa/index.js.map +1 -0
- package/dist/qa/types.d.ts +44 -0
- package/dist/qa/types.d.ts.map +1 -0
- package/dist/qa/types.js +12 -0
- package/dist/qa/types.js.map +1 -0
- package/dist/release-manager/decide.d.ts +26 -0
- package/dist/release-manager/decide.d.ts.map +1 -0
- package/dist/release-manager/decide.js +58 -0
- package/dist/release-manager/decide.js.map +1 -0
- package/dist/release-manager/github.d.ts +47 -0
- package/dist/release-manager/github.d.ts.map +1 -0
- package/dist/release-manager/github.js +66 -0
- package/dist/release-manager/github.js.map +1 -0
- package/dist/release-manager/index.d.ts +9 -0
- package/dist/release-manager/index.d.ts.map +1 -0
- package/dist/release-manager/index.js +9 -0
- package/dist/release-manager/index.js.map +1 -0
- package/dist/release-manager/scheduler.d.ts +30 -0
- package/dist/release-manager/scheduler.d.ts.map +1 -0
- package/dist/release-manager/scheduler.js +427 -0
- package/dist/release-manager/scheduler.js.map +1 -0
- package/dist/release-manager/slack-handler.d.ts +39 -0
- package/dist/release-manager/slack-handler.d.ts.map +1 -0
- package/dist/release-manager/slack-handler.js +124 -0
- package/dist/release-manager/slack-handler.js.map +1 -0
- package/dist/release-manager/state.d.ts +18 -0
- package/dist/release-manager/state.d.ts.map +1 -0
- package/dist/release-manager/state.js +154 -0
- package/dist/release-manager/state.js.map +1 -0
- package/dist/release-manager/triggers.d.ts +32 -0
- package/dist/release-manager/triggers.d.ts.map +1 -0
- package/dist/release-manager/triggers.js +82 -0
- package/dist/release-manager/triggers.js.map +1 -0
- package/dist/release-manager/types.d.ts +79 -0
- package/dist/release-manager/types.d.ts.map +1 -0
- package/dist/release-manager/types.js +48 -0
- package/dist/release-manager/types.js.map +1 -0
- package/dist/release-manager/versioning.d.ts +20 -0
- package/dist/release-manager/versioning.d.ts.map +1 -0
- package/dist/release-manager/versioning.js +60 -0
- package/dist/release-manager/versioning.js.map +1 -0
- package/dist/types.d.ts +48 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentic-deep-review-provider.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/agentic-deep-review-provider.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
+
const runDeepReviewMock = vi.fn();
|
|
3
|
+
vi.mock("../executor/deep-review.js", () => ({
|
|
4
|
+
runDeepReview: (...args) => runDeepReviewMock(...args),
|
|
5
|
+
deepFindingsToReviewFindings: (findings) => findings,
|
|
6
|
+
}));
|
|
7
|
+
const makeHandoff = () => ({
|
|
8
|
+
runId: "r1",
|
|
9
|
+
issueId: "i1",
|
|
10
|
+
stage: "review",
|
|
11
|
+
timestamp: new Date().toISOString(),
|
|
12
|
+
summary: "",
|
|
13
|
+
filesChanged: [],
|
|
14
|
+
approach: "",
|
|
15
|
+
context: { issueIntent: "do x", constraints: [], assumptions: [] },
|
|
16
|
+
tokenBudget: { contextTokensUsed: 0, recommendedMaxTurns: 0 },
|
|
17
|
+
});
|
|
18
|
+
describe("AgenticDeepReviewProvider", () => {
|
|
19
|
+
beforeEach(() => { runDeepReviewMock.mockReset(); });
|
|
20
|
+
it("returns a single ReviewModelRun with completed status on success", async () => {
|
|
21
|
+
runDeepReviewMock.mockResolvedValue({
|
|
22
|
+
findings: [
|
|
23
|
+
{ severity: "warning", file: "a.ts", line: 1, category: "x", description: "d", fix: "f" },
|
|
24
|
+
],
|
|
25
|
+
inputTokens: 100,
|
|
26
|
+
outputTokens: 50,
|
|
27
|
+
});
|
|
28
|
+
const { AgenticDeepReviewProvider } = await import("../executor/review/agentic-deep-review.js");
|
|
29
|
+
const provider = new AgenticDeepReviewProvider();
|
|
30
|
+
const handoff = makeHandoff();
|
|
31
|
+
const runs = await provider.runReview({
|
|
32
|
+
runId: "r1",
|
|
33
|
+
stageRunId: "s1",
|
|
34
|
+
workdir: "/tmp/x",
|
|
35
|
+
handoff,
|
|
36
|
+
baseRef: "main",
|
|
37
|
+
prNumber: null,
|
|
38
|
+
});
|
|
39
|
+
expect(runs).toHaveLength(1);
|
|
40
|
+
expect(runs[0].providerId).toBe("agentic");
|
|
41
|
+
expect(runs[0].status).toBe("completed");
|
|
42
|
+
expect(runs[0].modelId).toBe("claude-haiku-4-5-20251001");
|
|
43
|
+
expect(runs[0].findings).toHaveLength(1);
|
|
44
|
+
expect(runs[0].inputTokens).toBe(100);
|
|
45
|
+
expect(runs[0].outputTokens).toBe(50);
|
|
46
|
+
expect(runs[0].durationMs).toBeGreaterThanOrEqual(0);
|
|
47
|
+
expect(runDeepReviewMock).toHaveBeenCalledOnce();
|
|
48
|
+
expect(runDeepReviewMock).toHaveBeenCalledWith(handoff, "/tmp/x");
|
|
49
|
+
});
|
|
50
|
+
it("returns failed run with errorMessage when runDeepReview throws", async () => {
|
|
51
|
+
runDeepReviewMock.mockRejectedValue(new Error("agent sdk down"));
|
|
52
|
+
const { AgenticDeepReviewProvider } = await import("../executor/review/agentic-deep-review.js");
|
|
53
|
+
const provider = new AgenticDeepReviewProvider();
|
|
54
|
+
const handoff = makeHandoff();
|
|
55
|
+
const runs = await provider.runReview({
|
|
56
|
+
runId: "r1",
|
|
57
|
+
stageRunId: "s1",
|
|
58
|
+
workdir: "/tmp/x",
|
|
59
|
+
handoff,
|
|
60
|
+
baseRef: "main",
|
|
61
|
+
prNumber: null,
|
|
62
|
+
});
|
|
63
|
+
expect(runs).toHaveLength(1);
|
|
64
|
+
expect(runs[0].status).toBe("failed");
|
|
65
|
+
expect(runs[0].errorMessage).toContain("agent sdk down");
|
|
66
|
+
expect(runs[0].findings).toHaveLength(0);
|
|
67
|
+
expect(runs[0].durationMs).toBeGreaterThanOrEqual(0);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
//# sourceMappingURL=agentic-deep-review-provider.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentic-deep-review-provider.test.js","sourceRoot":"","sources":["../../src/__tests__/agentic-deep-review-provider.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -37,11 +37,26 @@ describe("audit_events immutability", () => {
|
|
|
37
37
|
.filter((file) => !allowed.some((a) => file.endsWith(a) || file === a));
|
|
38
38
|
expect(offenders, `Unauthorized audit_events mutation in:\n${offenders.join("\n")}`).toEqual([]);
|
|
39
39
|
});
|
|
40
|
-
it("logAuditEventUnchecked is only called from license.ts", () => {
|
|
40
|
+
it("logAuditEventUnchecked is only called from license.ts or Pro-tier feature modules", () => {
|
|
41
41
|
const repoRoot = path.resolve(__dirname, "../../../..");
|
|
42
|
+
// logAuditEventUnchecked is allowed in:
|
|
43
|
+
// 1. The writer itself (definition)
|
|
44
|
+
// 2. license.ts (license-validation failure path)
|
|
45
|
+
// 3. Pro-tier feature modules (PM agent, Release Manager) — their audit events
|
|
46
|
+
// must appear in the audit table whenever the Pro feature is licensed,
|
|
47
|
+
// independent of the Enterprise audit-log dashboard being unlocked.
|
|
48
|
+
// 4. This test file
|
|
42
49
|
const allowed = [
|
|
43
50
|
"packages/core/src/audit/writer.ts",
|
|
44
51
|
"packages/core/src/license.ts",
|
|
52
|
+
"packages/core/src/pm/scheduler.ts",
|
|
53
|
+
"packages/core/src/pm/actions/triage.ts",
|
|
54
|
+
"packages/core/src/pm/actions/promote.ts",
|
|
55
|
+
"packages/core/src/pm/actions/resolve-approvals.ts",
|
|
56
|
+
"packages/core/src/release-manager/scheduler.ts",
|
|
57
|
+
"packages/core/src/release-manager/slack-handler.ts",
|
|
58
|
+
"packages/core/src/qa/github.ts",
|
|
59
|
+
"packages/core/src/qa/gap.ts",
|
|
45
60
|
"packages/core/src/__tests__/audit-immutability.test.ts",
|
|
46
61
|
];
|
|
47
62
|
let matches = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit-immutability.test.js","sourceRoot":"","sources":["../../src/__tests__/audit-immutability.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QACxD,MAAM,OAAO,GAAG;YACd,sCAAsC;YACtC,qDAAqD;YACrD,wDAAwD;SACzD,CAAC;QAEF,MAAM,QAAQ,GAAG;YACf,iCAAiC;YACjC,iCAAiC;SAClC,CAAC;QAEF,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,YAAY,CACtB,KAAK,EACL,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,kBAAkB,CAAC,EAC9C,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,CACpC,CAAC;gBACF,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;YAC1D,CAAC;YAAC,MAAM,CAAC;gBACP,0DAA0D;YAC5D,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,OAAO;aACtB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;aAClC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;QAE1E,MAAM,CACJ,SAAS,EACT,2CAA2C,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAClE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"audit-immutability.test.js","sourceRoot":"","sources":["../../src/__tests__/audit-immutability.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"per-run-multi-model.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/cost/per-run-multi-model.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { computeRunCost } from "../../cost/per-run.js";
|
|
3
|
+
import { installTestProLicense, restoreLicense } from "../helpers/license.js";
|
|
4
|
+
// computeRunCost short-circuits to zero without an enterprise license.
|
|
5
|
+
beforeEach(async () => {
|
|
6
|
+
await installTestProLicense("enterprise");
|
|
7
|
+
});
|
|
8
|
+
afterEach(async () => {
|
|
9
|
+
await restoreLicense();
|
|
10
|
+
});
|
|
11
|
+
const config = {
|
|
12
|
+
costs: {
|
|
13
|
+
modelPricing: {
|
|
14
|
+
"claude-haiku-4-5-20251001": { inputPerMillion: 1, outputPerMillion: 5 },
|
|
15
|
+
"anthropic/claude-3.5-sonnet": { inputPerMillion: 3, outputPerMillion: 15 },
|
|
16
|
+
"claude-sonnet-4-6": { inputPerMillion: 3, outputPerMillion: 15 },
|
|
17
|
+
},
|
|
18
|
+
hourlyEngRate: 50,
|
|
19
|
+
timeSavedPerPrDefault: 4,
|
|
20
|
+
},
|
|
21
|
+
pipelineConfigs: {
|
|
22
|
+
"auto-implement": {
|
|
23
|
+
stageModels: { implement: "claude-sonnet-4-6" },
|
|
24
|
+
profile: { model: "claude-sonnet-4-6" },
|
|
25
|
+
timeSavedPerPr: 6,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
describe("computeRunCost — multi-model rollup (BEC-134)", () => {
|
|
30
|
+
it("uses modelRuns per-model pricing when present", () => {
|
|
31
|
+
const run = { pipelineKey: "auto-implement", status: "completed" };
|
|
32
|
+
const stages = [
|
|
33
|
+
{
|
|
34
|
+
stage: "review",
|
|
35
|
+
inputTokens: 1000, // stage-level totals (ignored when modelRuns present)
|
|
36
|
+
outputTokens: 500,
|
|
37
|
+
modelRuns: [
|
|
38
|
+
// 600/1_000_000 * 1 + 300/1_000_000 * 5 = 0.0006 + 0.0015 = 0.0021
|
|
39
|
+
{ modelId: "claude-haiku-4-5-20251001", inputTokens: 600, outputTokens: 300 },
|
|
40
|
+
// 400/1_000_000 * 3 + 200/1_000_000 * 15 = 0.0012 + 0.003 = 0.0042
|
|
41
|
+
{ modelId: "anthropic/claude-3.5-sonnet", inputTokens: 400, outputTokens: 200 },
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
const cost = computeRunCost(run, stages, config);
|
|
46
|
+
// total: 0.0021 + 0.0042 = 0.0063
|
|
47
|
+
expect(cost.dollars).toBeCloseTo(0.0063, 5);
|
|
48
|
+
// token totals come from model rows, not stage-level
|
|
49
|
+
expect(cost.inputTokens).toBe(1000); // 600 + 400
|
|
50
|
+
expect(cost.outputTokens).toBe(500); // 300 + 200
|
|
51
|
+
});
|
|
52
|
+
it("falls back to stage-level rollup when modelRuns is empty", () => {
|
|
53
|
+
const run = { pipelineKey: "auto-implement", status: "completed" };
|
|
54
|
+
const stages = [
|
|
55
|
+
{
|
|
56
|
+
stage: "review",
|
|
57
|
+
inputTokens: 1_000_000,
|
|
58
|
+
outputTokens: 500_000,
|
|
59
|
+
modelRuns: [], // empty → use stage-level fallback
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
const cost = computeRunCost(run, stages, config);
|
|
63
|
+
// review stage uses pipeline profile model: claude-sonnet-4-6 ($3/$15 per M)
|
|
64
|
+
// 1M * $3 + 0.5M * $15 = $3 + $7.5 = $10.5
|
|
65
|
+
expect(cost.dollars).toBeCloseTo(10.5, 2);
|
|
66
|
+
expect(cost.inputTokens).toBe(1_000_000);
|
|
67
|
+
expect(cost.outputTokens).toBe(500_000);
|
|
68
|
+
});
|
|
69
|
+
it("falls back to stage-level rollup when modelRuns is absent", () => {
|
|
70
|
+
const run = { pipelineKey: "auto-implement", status: "completed" };
|
|
71
|
+
const stages = [
|
|
72
|
+
// no modelRuns field at all — backward-compat for pre-BEC-134 rows
|
|
73
|
+
{ stage: "implement", inputTokens: 1_000_000, outputTokens: 1_000_000 },
|
|
74
|
+
];
|
|
75
|
+
const cost = computeRunCost(run, stages, config);
|
|
76
|
+
// implement stage model: claude-sonnet-4-6 ($3/$15 per M)
|
|
77
|
+
// 1M * $3 + 1M * $15 = $18
|
|
78
|
+
expect(cost.dollars).toBeCloseTo(18, 2);
|
|
79
|
+
});
|
|
80
|
+
it("mixes model-run and stage-level stages correctly", () => {
|
|
81
|
+
const run = { pipelineKey: "auto-implement", status: "completed" };
|
|
82
|
+
const stages = [
|
|
83
|
+
// implement: no modelRuns → stage-level fallback (claude-sonnet-4-6)
|
|
84
|
+
{ stage: "implement", inputTokens: 1_000_000, outputTokens: 0, modelRuns: [] },
|
|
85
|
+
// review: per-model pricing
|
|
86
|
+
{
|
|
87
|
+
stage: "review",
|
|
88
|
+
inputTokens: 0,
|
|
89
|
+
outputTokens: 0,
|
|
90
|
+
modelRuns: [
|
|
91
|
+
{ modelId: "claude-haiku-4-5-20251001", inputTokens: 1_000_000, outputTokens: 0 },
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
];
|
|
95
|
+
const cost = computeRunCost(run, stages, config);
|
|
96
|
+
// implement: 1M * $3 = $3
|
|
97
|
+
// review haiku: 1M * $1 = $1
|
|
98
|
+
// total: $4
|
|
99
|
+
expect(cost.dollars).toBeCloseTo(4, 5);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
//# sourceMappingURL=per-run-multi-model.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"per-run-multi-model.test.js","sourceRoot":"","sources":["../../../src/__tests__/cost/per-run-multi-model.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db-qa-gap-issues.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/db-qa-gap-issues.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { describe, it, expect, afterEach } from "vitest";
|
|
2
|
+
import { randomBytes, randomUUID } from "node:crypto";
|
|
3
|
+
import { unlinkSync } from "node:fs";
|
|
4
|
+
import { eq, and } from "drizzle-orm";
|
|
5
|
+
import { createDb } from "../db/index.js";
|
|
6
|
+
import { qaGapIssues, releaseDecisions } from "../db/schema.js";
|
|
7
|
+
function tmpDbPath() {
|
|
8
|
+
const id = randomBytes(8).toString("hex");
|
|
9
|
+
return `/tmp/laf-qa-gap-${id}.sqlite`;
|
|
10
|
+
}
|
|
11
|
+
describe("qa_gap_issues table", () => {
|
|
12
|
+
const paths = [];
|
|
13
|
+
async function makeDb() {
|
|
14
|
+
const path = tmpDbPath();
|
|
15
|
+
paths.push(path);
|
|
16
|
+
const db = await createDb({ driver: "sqlite", connectionString: path });
|
|
17
|
+
return { db: db };
|
|
18
|
+
}
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
for (const p of paths) {
|
|
21
|
+
try {
|
|
22
|
+
unlinkSync(p);
|
|
23
|
+
}
|
|
24
|
+
catch { }
|
|
25
|
+
try {
|
|
26
|
+
unlinkSync(p + "-wal");
|
|
27
|
+
}
|
|
28
|
+
catch { }
|
|
29
|
+
try {
|
|
30
|
+
unlinkSync(p + "-shm");
|
|
31
|
+
}
|
|
32
|
+
catch { }
|
|
33
|
+
}
|
|
34
|
+
paths.length = 0;
|
|
35
|
+
});
|
|
36
|
+
it("inserts and reads a qa_gap_issues row", async () => {
|
|
37
|
+
const { db } = await makeDb();
|
|
38
|
+
const id = `qg_${randomUUID()}`;
|
|
39
|
+
await db.insert(qaGapIssues).values({
|
|
40
|
+
id,
|
|
41
|
+
repoUrl: "https://github.com/org/repo",
|
|
42
|
+
branch: "main",
|
|
43
|
+
workflowPath: ".github/workflows/smoke.yml",
|
|
44
|
+
linearIssueId: "BEC-150",
|
|
45
|
+
});
|
|
46
|
+
const rows = await db.select().from(qaGapIssues).where(eq(qaGapIssues.id, id));
|
|
47
|
+
expect(rows).toHaveLength(1);
|
|
48
|
+
expect(rows[0].linearIssueId).toBe("BEC-150");
|
|
49
|
+
expect(rows[0].resolvedAt).toBeNull();
|
|
50
|
+
});
|
|
51
|
+
it("partial UNIQUE prevents re-filing while resolved_at is null", async () => {
|
|
52
|
+
const { db } = await makeDb();
|
|
53
|
+
await db.insert(qaGapIssues).values({
|
|
54
|
+
id: `qg_${randomUUID()}`,
|
|
55
|
+
repoUrl: "https://github.com/org/repo",
|
|
56
|
+
branch: "main",
|
|
57
|
+
workflowPath: ".github/workflows/smoke.yml",
|
|
58
|
+
linearIssueId: "BEC-150",
|
|
59
|
+
});
|
|
60
|
+
await expect(db.insert(qaGapIssues).values({
|
|
61
|
+
id: `qg_${randomUUID()}`,
|
|
62
|
+
repoUrl: "https://github.com/org/repo",
|
|
63
|
+
branch: "main",
|
|
64
|
+
workflowPath: ".github/workflows/smoke.yml",
|
|
65
|
+
linearIssueId: "BEC-151",
|
|
66
|
+
})).rejects.toThrow();
|
|
67
|
+
});
|
|
68
|
+
it("allows re-filing after the previous issue is resolved", async () => {
|
|
69
|
+
const { db } = await makeDb();
|
|
70
|
+
const firstId = `qg_${randomUUID()}`;
|
|
71
|
+
await db.insert(qaGapIssues).values({
|
|
72
|
+
id: firstId,
|
|
73
|
+
repoUrl: "https://github.com/org/repo",
|
|
74
|
+
branch: "main",
|
|
75
|
+
workflowPath: ".github/workflows/smoke.yml",
|
|
76
|
+
linearIssueId: "BEC-150",
|
|
77
|
+
});
|
|
78
|
+
await db.update(qaGapIssues)
|
|
79
|
+
.set({ resolvedAt: new Date() })
|
|
80
|
+
.where(eq(qaGapIssues.id, firstId));
|
|
81
|
+
// Second filing now succeeds
|
|
82
|
+
await db.insert(qaGapIssues).values({
|
|
83
|
+
id: `qg_${randomUUID()}`,
|
|
84
|
+
repoUrl: "https://github.com/org/repo",
|
|
85
|
+
branch: "main",
|
|
86
|
+
workflowPath: ".github/workflows/smoke.yml",
|
|
87
|
+
linearIssueId: "BEC-160",
|
|
88
|
+
});
|
|
89
|
+
const rows = await db.select().from(qaGapIssues).where(and(eq(qaGapIssues.repoUrl, "https://github.com/org/repo"), eq(qaGapIssues.workflowPath, ".github/workflows/smoke.yml")));
|
|
90
|
+
expect(rows).toHaveLength(2);
|
|
91
|
+
});
|
|
92
|
+
it("releaseDecisions has qaRunId and qaRunSha columns", async () => {
|
|
93
|
+
const { db } = await makeDb();
|
|
94
|
+
const id = `rd_${randomUUID()}`;
|
|
95
|
+
await db.insert(releaseDecisions).values({
|
|
96
|
+
id,
|
|
97
|
+
repoUrl: "https://github.com/org/repo",
|
|
98
|
+
branch: "main",
|
|
99
|
+
decidedAt: new Date(),
|
|
100
|
+
decision: "skip",
|
|
101
|
+
reason: "qa_running",
|
|
102
|
+
triggerStateJson: "{}",
|
|
103
|
+
attemptCount: 0,
|
|
104
|
+
qaRunId: 12345,
|
|
105
|
+
qaRunSha: "abcdef0",
|
|
106
|
+
});
|
|
107
|
+
const rows = await db.select().from(releaseDecisions).where(eq(releaseDecisions.id, id));
|
|
108
|
+
expect(rows).toHaveLength(1);
|
|
109
|
+
expect(rows[0].qaRunId).toBe(12345);
|
|
110
|
+
expect(rows[0].qaRunSha).toBe("abcdef0");
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
//# sourceMappingURL=db-qa-gap-issues.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db-qa-gap-issues.test.js","sourceRoot":"","sources":["../../src/__tests__/db-qa-gap-issues.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,EAAE,EAAU,GAAG,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEhE,SAAS,SAAS;IAChB,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,mBAAmB,EAAE,SAAS,CAAC;AACxC,CAAC;AAED,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,UAAU,MAAM;QACnB,MAAM,IAAI,GAAG,SAAS,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;QACxE,OAAO,EAAE,EAAE,EAAE,EAAS,EAAE,CAAC;IAC3B,CAAC;IAED,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,IAAI,CAAC;gBAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YAC/B,IAAI,CAAC;gBAAC,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YACxC,IAAI,CAAC;gBAAC,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QAC1C,CAAC;QACD,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,MAAM,EAAE,CAAC;QAC9B,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,EAAE,CAAC;QAChC,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;YAClC,EAAE;YACF,OAAO,EAAE,6BAA6B;YACtC,MAAM,EAAE,MAAM;YACd,YAAY,EAAE,6BAA6B;YAC3C,aAAa,EAAE,SAAS;SACzB,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC/E,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;QAC3E,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,MAAM,EAAE,CAAC;QAC9B,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;YAClC,EAAE,EAAE,MAAM,UAAU,EAAE,EAAE;YACxB,OAAO,EAAE,6BAA6B;YACtC,MAAM,EAAE,MAAM;YACd,YAAY,EAAE,6BAA6B;YAC3C,aAAa,EAAE,SAAS;SACzB,CAAC,CAAC;QACH,MAAM,MAAM,CACV,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;YAC5B,EAAE,EAAE,MAAM,UAAU,EAAE,EAAE;YACxB,OAAO,EAAE,6BAA6B;YACtC,MAAM,EAAE,MAAM;YACd,YAAY,EAAE,6BAA6B;YAC3C,aAAa,EAAE,SAAS;SACzB,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,MAAM,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,EAAE,CAAC;QACrC,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;YAClC,EAAE,EAAE,OAAO;YACX,OAAO,EAAE,6BAA6B;YACtC,MAAM,EAAE,MAAM;YACd,YAAY,EAAE,6BAA6B;YAC3C,aAAa,EAAE,SAAS;SACzB,CAAC,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC;aACzB,GAAG,CAAC,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;aAC/B,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;QACtC,6BAA6B;QAC7B,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;YAClC,EAAE,EAAE,MAAM,UAAU,EAAE,EAAE;YACxB,OAAO,EAAE,6BAA6B;YACtC,MAAM,EAAE,MAAM;YACd,YAAY,EAAE,6BAA6B;YAC3C,aAAa,EAAE,SAAS;SACzB,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,KAAK,CACpD,GAAG,CACD,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,6BAA6B,CAAC,EACtD,EAAE,CAAC,WAAW,CAAC,YAAY,EAAE,6BAA6B,CAAC,CAC5D,CACF,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,MAAM,EAAE,CAAC;QAC9B,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,EAAE,CAAC;QAChC,MAAM,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC;YACvC,EAAE;YACF,OAAO,EAAE,6BAA6B;YACtC,MAAM,EAAE,MAAM;YACd,SAAS,EAAE,IAAI,IAAI,EAAE;YACrB,QAAQ,EAAE,MAAM;YAChB,MAAM,EAAE,YAAY;YACpB,gBAAgB,EAAE,IAAI;YACtB,YAAY,EAAE,CAAC;YACf,OAAO,EAAE,KAAK;YACd,QAAQ,EAAE,SAAS;SACpB,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QACzF,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db-release-decisions.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/db-release-decisions.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { describe, it, expect, afterEach } from "vitest";
|
|
2
|
+
import { randomBytes, randomUUID } from "node:crypto";
|
|
3
|
+
import { unlinkSync } from "node:fs";
|
|
4
|
+
import { eq, and } from "drizzle-orm";
|
|
5
|
+
import { createDb } from "../db/index.js";
|
|
6
|
+
import { releaseDecisions, releaseApprovals } from "../db/schema.js";
|
|
7
|
+
function tmpDbPath() {
|
|
8
|
+
const id = randomBytes(8).toString("hex");
|
|
9
|
+
return `/tmp/laf-rm-test-${id}.sqlite`;
|
|
10
|
+
}
|
|
11
|
+
describe("release-manager DB tables", () => {
|
|
12
|
+
const paths = [];
|
|
13
|
+
async function makeDb() {
|
|
14
|
+
const path = tmpDbPath();
|
|
15
|
+
paths.push(path);
|
|
16
|
+
const db = await createDb({ driver: "sqlite", connectionString: path });
|
|
17
|
+
return { db: db };
|
|
18
|
+
}
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
for (const p of paths) {
|
|
21
|
+
try {
|
|
22
|
+
unlinkSync(p);
|
|
23
|
+
}
|
|
24
|
+
catch { /* ignore */ }
|
|
25
|
+
try {
|
|
26
|
+
unlinkSync(p + "-wal");
|
|
27
|
+
}
|
|
28
|
+
catch { /* ignore */ }
|
|
29
|
+
try {
|
|
30
|
+
unlinkSync(p + "-shm");
|
|
31
|
+
}
|
|
32
|
+
catch { /* ignore */ }
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
it("inserts and reads a release_decisions row", async () => {
|
|
36
|
+
const { db } = await makeDb();
|
|
37
|
+
const id = `rd_${randomUUID()}`;
|
|
38
|
+
await db.insert(releaseDecisions).values({
|
|
39
|
+
id,
|
|
40
|
+
repoUrl: "https://github.com/org/repo",
|
|
41
|
+
branch: "main",
|
|
42
|
+
decidedAt: new Date(),
|
|
43
|
+
decision: "skip",
|
|
44
|
+
reason: "timeSinceLastHours not met",
|
|
45
|
+
triggerStateJson: JSON.stringify({ mergedPRs: 3 }),
|
|
46
|
+
attemptCount: 0,
|
|
47
|
+
});
|
|
48
|
+
const rows = await db.select().from(releaseDecisions).where(eq(releaseDecisions.id, id));
|
|
49
|
+
expect(rows).toHaveLength(1);
|
|
50
|
+
expect(rows[0].decision).toBe("skip");
|
|
51
|
+
expect(rows[0].reason).toBe("timeSinceLastHours not met");
|
|
52
|
+
});
|
|
53
|
+
it("enforces UNIQUE(repo_url, branch, approved_by) WHERE consumed_at IS NULL — second pending approve from same user fails", async () => {
|
|
54
|
+
const { db } = await makeDb();
|
|
55
|
+
await db.insert(releaseApprovals).values({
|
|
56
|
+
id: `ra_${randomUUID()}`,
|
|
57
|
+
repoUrl: "https://github.com/org/repo",
|
|
58
|
+
branch: "main",
|
|
59
|
+
approvedAt: new Date(),
|
|
60
|
+
approvedBy: "U123",
|
|
61
|
+
});
|
|
62
|
+
await expect(db.insert(releaseApprovals).values({
|
|
63
|
+
id: `ra_${randomUUID()}`,
|
|
64
|
+
repoUrl: "https://github.com/org/repo",
|
|
65
|
+
branch: "main",
|
|
66
|
+
approvedAt: new Date(),
|
|
67
|
+
approvedBy: "U123",
|
|
68
|
+
})).rejects.toThrow();
|
|
69
|
+
});
|
|
70
|
+
it("allows a second approve from the same user once the first is consumed", async () => {
|
|
71
|
+
const { db } = await makeDb();
|
|
72
|
+
const firstId = `ra_${randomUUID()}`;
|
|
73
|
+
await db.insert(releaseApprovals).values({
|
|
74
|
+
id: firstId,
|
|
75
|
+
repoUrl: "https://github.com/org/repo",
|
|
76
|
+
branch: "main",
|
|
77
|
+
approvedAt: new Date(),
|
|
78
|
+
approvedBy: "U123",
|
|
79
|
+
});
|
|
80
|
+
await db.update(releaseApprovals)
|
|
81
|
+
.set({ consumedAt: new Date(), consumedByDecisionId: "rd_consumed" })
|
|
82
|
+
.where(eq(releaseApprovals.id, firstId));
|
|
83
|
+
// Second approve should now succeed
|
|
84
|
+
await db.insert(releaseApprovals).values({
|
|
85
|
+
id: `ra_${randomUUID()}`,
|
|
86
|
+
repoUrl: "https://github.com/org/repo",
|
|
87
|
+
branch: "main",
|
|
88
|
+
approvedAt: new Date(),
|
|
89
|
+
approvedBy: "U123",
|
|
90
|
+
});
|
|
91
|
+
const rows = await db
|
|
92
|
+
.select()
|
|
93
|
+
.from(releaseApprovals)
|
|
94
|
+
.where(and(eq(releaseApprovals.repoUrl, "https://github.com/org/repo"), eq(releaseApprovals.approvedBy, "U123")));
|
|
95
|
+
expect(rows).toHaveLength(2);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
//# sourceMappingURL=db-release-decisions.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db-release-decisions.test.js","sourceRoot":"","sources":["../../src/__tests__/db-release-decisions.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db-review-model-runs.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/db-review-model-runs.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import Database from "better-sqlite3";
|
|
3
|
+
import { runMigrationsSqlite } from "../db/migrator.js";
|
|
4
|
+
import { insertReviewModelRuns } from "../db/review-model-runs.js";
|
|
5
|
+
import { drizzle as drizzleSqlite } from "drizzle-orm/better-sqlite3";
|
|
6
|
+
describe("review_model_runs migration (sqlite)", () => {
|
|
7
|
+
it("creates the table with expected columns", () => {
|
|
8
|
+
const db = new Database(":memory:");
|
|
9
|
+
runMigrationsSqlite(db);
|
|
10
|
+
const cols = db
|
|
11
|
+
.prepare("PRAGMA table_info(review_model_runs)")
|
|
12
|
+
.all();
|
|
13
|
+
const names = cols.map((c) => c.name).sort();
|
|
14
|
+
expect(names).toEqual([
|
|
15
|
+
"completed_at",
|
|
16
|
+
"duration_ms",
|
|
17
|
+
"error_message",
|
|
18
|
+
"id",
|
|
19
|
+
"input_tokens",
|
|
20
|
+
"model_id",
|
|
21
|
+
"output_tokens",
|
|
22
|
+
"provider_id",
|
|
23
|
+
"stage_run_id",
|
|
24
|
+
"started_at",
|
|
25
|
+
"status",
|
|
26
|
+
"truncated_files",
|
|
27
|
+
].sort());
|
|
28
|
+
});
|
|
29
|
+
it("creates an index on stage_run_id", () => {
|
|
30
|
+
const db = new Database(":memory:");
|
|
31
|
+
runMigrationsSqlite(db);
|
|
32
|
+
const indexes = db
|
|
33
|
+
.prepare("PRAGMA index_list(review_model_runs)")
|
|
34
|
+
.all();
|
|
35
|
+
expect(indexes.some((i) => i.name.includes("stage_run_id"))).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
it("inserts and reads rows", () => {
|
|
38
|
+
const db = new Database(":memory:");
|
|
39
|
+
runMigrationsSqlite(db);
|
|
40
|
+
// Need a stage_run row first (FK)
|
|
41
|
+
db.prepare("INSERT INTO pipeline_runs (id, issue_id, issue_title, pipeline_key, repo_url, status, started_at) VALUES (?, ?, ?, ?, ?, ?, ?)").run("p1", "i1", "t", "k", "u", "running", Math.floor(Date.now() / 1000));
|
|
42
|
+
db.prepare("INSERT INTO stage_runs (id, pipeline_run_id, stage, status, started_at) VALUES (?, ?, ?, ?, ?)").run("s1", "p1", "review", "completed", Math.floor(Date.now() / 1000));
|
|
43
|
+
db.prepare("INSERT INTO review_model_runs (id, stage_run_id, provider_id, model_id, status, input_tokens, output_tokens, duration_ms) VALUES (?, ?, ?, ?, ?, ?, ?, ?)").run("r1", "s1", "openrouter", "anthropic/claude-3.5-sonnet", "completed", 100, 50, 1000);
|
|
44
|
+
const rows = db
|
|
45
|
+
.prepare("SELECT * FROM review_model_runs WHERE stage_run_id = ?")
|
|
46
|
+
.all("s1");
|
|
47
|
+
expect(rows).toHaveLength(1);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
describe("insertReviewModelRuns", () => {
|
|
51
|
+
it("writes one row per ReviewModelRun", async () => {
|
|
52
|
+
const sqliteDb = new Database(":memory:");
|
|
53
|
+
runMigrationsSqlite(sqliteDb);
|
|
54
|
+
sqliteDb.prepare("INSERT INTO pipeline_runs (id, issue_id, issue_title, pipeline_key, repo_url, status, started_at) VALUES (?, ?, ?, ?, ?, ?, ?)").run("p1", "i1", "t", "k", "u", "running", Math.floor(Date.now() / 1000));
|
|
55
|
+
sqliteDb.prepare("INSERT INTO stage_runs (id, pipeline_run_id, stage, status, started_at) VALUES (?, ?, ?, ?, ?)").run("s1", "p1", "review", "completed", Math.floor(Date.now() / 1000));
|
|
56
|
+
const db = drizzleSqlite(sqliteDb);
|
|
57
|
+
await insertReviewModelRuns(db, "s1", [
|
|
58
|
+
{
|
|
59
|
+
modelId: "anthropic/claude-3.5-sonnet",
|
|
60
|
+
providerId: "openrouter",
|
|
61
|
+
status: "completed",
|
|
62
|
+
findings: [],
|
|
63
|
+
inputTokens: 100,
|
|
64
|
+
outputTokens: 50,
|
|
65
|
+
durationMs: 1000,
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
modelId: "openai/gpt-4o",
|
|
69
|
+
providerId: "openrouter",
|
|
70
|
+
status: "failed",
|
|
71
|
+
findings: [],
|
|
72
|
+
inputTokens: 0,
|
|
73
|
+
outputTokens: 0,
|
|
74
|
+
durationMs: 200,
|
|
75
|
+
errorMessage: "rate limited",
|
|
76
|
+
truncatedFiles: 2,
|
|
77
|
+
},
|
|
78
|
+
]);
|
|
79
|
+
const rows = sqliteDb
|
|
80
|
+
.prepare("SELECT * FROM review_model_runs WHERE stage_run_id = ? ORDER BY model_id")
|
|
81
|
+
.all("s1");
|
|
82
|
+
expect(rows).toHaveLength(2);
|
|
83
|
+
expect(rows[0].model_id).toBe("anthropic/claude-3.5-sonnet");
|
|
84
|
+
expect(rows[0].input_tokens).toBe(100);
|
|
85
|
+
expect(rows[1].status).toBe("failed");
|
|
86
|
+
expect(rows[1].error_message).toBe("rate limited");
|
|
87
|
+
expect(rows[1].truncated_files).toBe(2);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
//# sourceMappingURL=db-review-model-runs.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db-review-model-runs.test.js","sourceRoot":"","sources":["../../src/__tests__/db-review-model-runs.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* E2E fanout integration test — BEC-134 Task 14
|
|
3
|
+
*
|
|
4
|
+
* Drives `runReviewProviders` end-to-end with:
|
|
5
|
+
* - Real in-memory SQLite DB (better-sqlite3 + runMigrationsSqlite + Drizzle)
|
|
6
|
+
* so actual review_model_runs rows are written and queryable
|
|
7
|
+
* - Mocked OpenRouter HTTP client (avoids network)
|
|
8
|
+
* - Mocked agentic deep-review (avoids Claude SDK)
|
|
9
|
+
*
|
|
10
|
+
* Verifies the four required properties:
|
|
11
|
+
* 1. Both providers (agentic + openrouter) ran
|
|
12
|
+
* 2. review_model_runs rows were persisted for both providers
|
|
13
|
+
* 3. Agentic findings appear in agenticFindings (merge-gate path)
|
|
14
|
+
* 4. Fanout findings do NOT appear in agenticFindings (advisory only)
|
|
15
|
+
*/
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=e2e-fanout.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"e2e-fanout.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/e2e-fanout.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
|