mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-31 22:24:16 +01:00
Implement typed task watchdog proof outcomes
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
189fc9b881
commit
b7d72340d5
11 files changed
+638
-42
No files matched your search
@@ -0,0 +1,65 @@
|
||||
CREATE TABLE IF NOT EXISTS "issue_watchdog_proof_outcomes" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"company_id" uuid NOT NULL,
|
||||
"watchdog_id" uuid NOT NULL,
|
||||
"source_issue_id" uuid NOT NULL,
|
||||
"watchdog_issue_id" uuid,
|
||||
"target_issue_id" uuid,
|
||||
"outcome" text NOT NULL,
|
||||
"method" text NOT NULL,
|
||||
"observed_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"result_classification" text NOT NULL,
|
||||
"redacted_details" jsonb DEFAULT '{}'::jsonb NOT NULL,
|
||||
"stop_fingerprint" text NOT NULL,
|
||||
"proof_obligation_fingerprint" text NOT NULL,
|
||||
"created_by_run_id" uuid,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
CONSTRAINT "issue_watchdog_proof_outcomes_outcome_chk"
|
||||
CHECK ("outcome" IN ('accepted', 'restored', 'deferred', 'failed', 'dismissed'))
|
||||
);
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "issue_watchdog_proof_outcomes" ADD CONSTRAINT "issue_watchdog_proof_outcomes_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "issue_watchdog_proof_outcomes" ADD CONSTRAINT "issue_watchdog_proof_outcomes_watchdog_id_issue_watchdogs_id_fk" FOREIGN KEY ("watchdog_id") REFERENCES "public"."issue_watchdogs"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "issue_watchdog_proof_outcomes" ADD CONSTRAINT "issue_watchdog_proof_outcomes_source_issue_id_issues_id_fk" FOREIGN KEY ("source_issue_id") REFERENCES "public"."issues"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "issue_watchdog_proof_outcomes" ADD CONSTRAINT "issue_watchdog_proof_outcomes_watchdog_issue_id_issues_id_fk" FOREIGN KEY ("watchdog_issue_id") REFERENCES "public"."issues"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "issue_watchdog_proof_outcomes" ADD CONSTRAINT "issue_watchdog_proof_outcomes_target_issue_id_issues_id_fk" FOREIGN KEY ("target_issue_id") REFERENCES "public"."issues"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "issue_watchdog_proof_outcomes" ADD CONSTRAINT "issue_watchdog_proof_outcomes_created_by_run_id_heartbeat_runs_id_fk" FOREIGN KEY ("created_by_run_id") REFERENCES "public"."heartbeat_runs"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "issue_watchdog_proof_outcomes_company_watchdog_observed_idx"
|
||||
ON "issue_watchdog_proof_outcomes" USING btree ("company_id","watchdog_id","observed_at");
|
||||
--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "issue_watchdog_proof_outcomes_company_source_idx"
|
||||
ON "issue_watchdog_proof_outcomes" USING btree ("company_id","source_issue_id");
|
||||
--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "issue_watchdog_proof_outcomes_unique_proof_uq"
|
||||
ON "issue_watchdog_proof_outcomes" USING btree ("company_id","watchdog_id","stop_fingerprint","proof_obligation_fingerprint");
|
||||
@@ -778,6 +778,13 @@
|
||||
"when": 1781902400000,
|
||||
"tag": "0110_document_company_cascade",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 111,
|
||||
"version": "7",
|
||||
"when": 1782340000000,
|
||||
"tag": "0111_task_watchdog_proof_outcomes",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -33,6 +33,7 @@ export { projectGoals } from "./project_goals.js";
|
||||
export { goals } from "./goals.js";
|
||||
export { issues } from "./issues.js";
|
||||
export { issueWatchdogs } from "./issue_watchdogs.js";
|
||||
export { issueWatchdogProofOutcomes } from "./issue_watchdog_proof_outcomes.js";
|
||||
export { issuePlanDecompositions } from "./issue_plan_decompositions.js";
|
||||
export { issueRecoveryActions } from "./issue_recovery_actions.js";
|
||||
export { issueReferenceMentions } from "./issue_reference_mentions.js";
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import { sql } from "drizzle-orm";
|
||||
import { check, index, jsonb, pgTable, text, timestamp, uniqueIndex, uuid } from "drizzle-orm/pg-core";
|
||||
import { companies } from "./companies.js";
|
||||
import { heartbeatRuns } from "./heartbeat_runs.js";
|
||||
import { issues } from "./issues.js";
|
||||
import { issueWatchdogs } from "./issue_watchdogs.js";
|
||||
|
||||
export const issueWatchdogProofOutcomes = pgTable(
|
||||
"issue_watchdog_proof_outcomes",
|
||||
{
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }),
|
||||
watchdogId: uuid("watchdog_id").notNull().references(() => issueWatchdogs.id, { onDelete: "cascade" }),
|
||||
sourceIssueId: uuid("source_issue_id").notNull().references(() => issues.id, { onDelete: "cascade" }),
|
||||
watchdogIssueId: uuid("watchdog_issue_id").references(() => issues.id, { onDelete: "set null" }),
|
||||
targetIssueId: uuid("target_issue_id").references(() => issues.id, { onDelete: "set null" }),
|
||||
outcome: text("outcome").notNull(),
|
||||
method: text("method").notNull(),
|
||||
observedAt: timestamp("observed_at", { withTimezone: true }).notNull().defaultNow(),
|
||||
resultClassification: text("result_classification").notNull(),
|
||||
redactedDetails: jsonb("redacted_details").$type<Record<string, unknown>>().notNull().default({}),
|
||||
stopFingerprint: text("stop_fingerprint").notNull(),
|
||||
proofObligationFingerprint: text("proof_obligation_fingerprint").notNull(),
|
||||
createdByRunId: uuid("created_by_run_id").references(() => heartbeatRuns.id, { onDelete: "set null" }),
|
||||
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
||||
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
|
||||
},
|
||||
(table) => ({
|
||||
companyWatchdogObservedIdx: index("issue_watchdog_proof_outcomes_company_watchdog_observed_idx").on(
|
||||
table.companyId,
|
||||
table.watchdogId,
|
||||
table.observedAt,
|
||||
),
|
||||
companySourceIdx: index("issue_watchdog_proof_outcomes_company_source_idx").on(
|
||||
table.companyId,
|
||||
table.sourceIssueId,
|
||||
),
|
||||
uniqueProofIdx: uniqueIndex("issue_watchdog_proof_outcomes_unique_proof_uq").on(
|
||||
table.companyId,
|
||||
table.watchdogId,
|
||||
table.stopFingerprint,
|
||||
table.proofObligationFingerprint,
|
||||
),
|
||||
outcomeCheck: check(
|
||||
"issue_watchdog_proof_outcomes_outcome_chk",
|
||||
sql`${table.outcome} IN ('accepted', 'restored', 'deferred', 'failed', 'dismissed')`,
|
||||
),
|
||||
}),
|
||||
);
|
||||
@@ -271,6 +271,14 @@ export type PluginIssueOriginKind = `plugin:${string}`;
|
||||
export type IssueOriginKind = BuiltInIssueOriginKind | PluginIssueOriginKind;
|
||||
export const ISSUE_WATCHDOG_DISCOVERY_KINDS = ["product_bug", "platform_bug"] as const;
|
||||
export type IssueWatchdogDiscoveryKind = (typeof ISSUE_WATCHDOG_DISCOVERY_KINDS)[number];
|
||||
export const ISSUE_WATCHDOG_PROOF_OUTCOMES = [
|
||||
"accepted",
|
||||
"restored",
|
||||
"deferred",
|
||||
"failed",
|
||||
"dismissed",
|
||||
] as const;
|
||||
export type IssueWatchdogProofOutcome = (typeof ISSUE_WATCHDOG_PROOF_OUTCOMES)[number];
|
||||
export const ISSUE_SURFACE_VISIBILITIES = ["default", "plugin_operation"] as const;
|
||||
export type IssueSurfaceVisibility = (typeof ISSUE_SURFACE_VISIBILITIES)[number];
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ export {
|
||||
ISSUE_ORIGIN_KINDS,
|
||||
TASK_WATCHDOG_PRODUCT_BUG_ORIGIN_KIND,
|
||||
ISSUE_WATCHDOG_DISCOVERY_KINDS,
|
||||
ISSUE_WATCHDOG_PROOF_OUTCOMES,
|
||||
ISSUE_SURFACE_VISIBILITIES,
|
||||
ISSUE_RECOVERY_ACTION_KINDS,
|
||||
ISSUE_RECOVERY_ACTION_STATUSES,
|
||||
@@ -208,6 +209,7 @@ export {
|
||||
type PluginIssueOriginKind,
|
||||
type IssueOriginKind,
|
||||
type IssueWatchdogDiscoveryKind,
|
||||
type IssueWatchdogProofOutcome,
|
||||
type IssueSurfaceVisibility,
|
||||
type IssueRecoveryActionKind,
|
||||
type IssueRecoveryActionStatus,
|
||||
|
||||
@@ -25,6 +25,7 @@ import type {
|
||||
IssueThreadInteractionKind,
|
||||
IssueThreadInteractionStatus,
|
||||
IssueStatus,
|
||||
IssueWatchdogProofOutcome,
|
||||
} from "../constants.js";
|
||||
import type { Goal } from "./goal.js";
|
||||
import type { Project, ProjectWorkspace } from "./project.js";
|
||||
@@ -503,6 +504,21 @@ export interface IssueExecutionDecision {
|
||||
|
||||
export type IssueWatchdogStatus = "active" | "disabled";
|
||||
|
||||
export interface IssueWatchdogProofOutcomeSummary {
|
||||
id: string;
|
||||
outcome: IssueWatchdogProofOutcome;
|
||||
targetIssueId: string | null;
|
||||
method: string;
|
||||
observedAt: Date;
|
||||
resultClassification: string;
|
||||
redactedDetails: Record<string, unknown>;
|
||||
stopFingerprint: string;
|
||||
proofObligationFingerprint: string;
|
||||
createdByRunId: string | null;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface IssueWatchdogSummary {
|
||||
id: string;
|
||||
companyId: string;
|
||||
@@ -515,6 +531,7 @@ export interface IssueWatchdogSummary {
|
||||
lastReviewedFingerprint: string | null;
|
||||
lastTriggeredAt: Date | null;
|
||||
lastCompletedAt: Date | null;
|
||||
latestProofOutcome?: IssueWatchdogProofOutcomeSummary | null;
|
||||
triggerCount: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
|
||||
Reference in new issue
Block a user