Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions deploy/helm/paperclip/templates/deployment-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,10 @@ spec:
- name: PAPERCLIP_PR_COMMENT_REVIEW_GATE_STATUS_CONTEXT
value: {{ . | quote }}
{{- end }}
{{- with ((.Values.githubApp).prCommentReviewGateRetiredStatusContexts) }}
- name: PAPERCLIP_PR_COMMENT_REVIEW_GATE_RETIRED_STATUS_CONTEXTS
value: {{ . | quote }}
{{- end }}
{{- end }}
{{- with .Values.env.extra }}
{{- toYaml . | nindent 12 }}
Expand Down
4 changes: 4 additions & 0 deletions deploy/helm/paperclip/templates/statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -938,6 +938,10 @@ spec:
- name: PAPERCLIP_PR_COMMENT_REVIEW_GATE_STATUS_CONTEXT
value: {{ . | quote }}
{{- end }}
{{- with ((.Values.githubApp).prCommentReviewGateRetiredStatusContexts) }}
- name: PAPERCLIP_PR_COMMENT_REVIEW_GATE_RETIRED_STATUS_CONTEXTS
value: {{ . | quote }}
{{- end }}
{{- end }}
{{- with .Values.env.extra }}
{{- toYaml . | nindent 12 }}
Expand Down
37 changes: 33 additions & 4 deletions deploy/helm/paperclip/values.blockcast.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -417,10 +417,19 @@ githubApp:
# contexts it has observed recently, and this repo has never carried a commit
# status, so the context has to be posted at least once before a human can
# select it. Until then this is observe-only.
prCommentReviewGateStatusContext: "review/ally-comment"
# NOTE: `prReviewGateStatusContext` is shared by the legacy failure status
# and the durable review-gate authority below. The latter owns
# `review/ally-complete`, including its success writer.
#
# Deliberately NOT under `review/` (BLO-29711). This gate reads only the
# comment-shaped surface, so "nothing attests this head" is a legitimate and
# common outcome for a formally-reviewed PR, and it must stay green there or
# every such PR deadlocks. A green under `review/` reads as review evidence,
# which this gate cannot supply — so the fail-open and the namespace cannot
# coexist. Moving the namespace is the half that is safe to change.
# Verified before renaming: `review/ally-comment` was not a required check on
# paperclip `master` (required: `verify`) nor on penstock-llm-proxy-core
# `main` (required: validate-and-build, secret-scan, redaction-tests,
# secrets-controls-static-check, review/ally-complete), so this drops nothing.
prCommentReviewGateStatusContext: "gate/ally-comment-findings"
prCommentReviewGateRetiredStatusContexts: "review/ally-comment"
# PEN-2073 rollout order:
# 1. Freeze review-gate merges.
# 2. Deploy this producer migration/code with both flags false; wait for every pod.
Expand All @@ -438,6 +447,26 @@ githubApp:
- Blockcast/penstock-llm-proxy-core
reviewGateExpectedAppId: "3966421"
reviewGateExpectedInstallationId: "138085375"
# NOTE: `prReviewGateStatusContext` IS set here (below), and it is required to
# be: the chart hard-fails when `reviewGateCaptureEnabled` is true and this is
# empty (templates/_helpers.tpl). Two server writers share the one field, and
# neither posts success:
# * the legacy failure writer — `queueFailedPrReviewGateStatus` in
# server/src/services/heartbeat.ts — posts state=failure only (reviewer
# chain exhausted / non-retryable external lifecycle end);
# * the durable review-gate authority —
# server/src/services/github-review-gate-authority.ts — posts
# state=pending only, then hands off via `repository_dispatch`
# (`review_gate_reconcile`) to the consumer in the Penstock repo. That
# external consumer is the success writer for this context; nothing in
# this repo, server or workflow, ever posts success for it.
# Both flags above are false today, so only the legacy failure writer can
# fire; the authority is pre-configured for the rollout, not yet live.
# Therefore: do NOT mark this context required on paperclip `master`. With no
# in-repo success writer, every healthy PR would sit at "Expected — waiting
# for status" forever. Requiring it is correct only where an external producer
# posts success — step 7 of the rollout above, on penstock-llm-proxy-core, or
# a pre-existing external writer as on onprem-k8s.
prReviewGateStatusContext: review/ally-complete

# paperclip-plugin-gbrain reads per-agent OAuth client credentials through
Expand Down
6 changes: 6 additions & 0 deletions deploy/helm/paperclip/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,12 @@ githubApp:
# required in branch protection so Critical/Important comment findings block
# the head they explicitly attest to. Requires `statuses: write`.
prCommentReviewGateStatusContext: ""
# -- Contexts this gate previously published to. Commit statuses cannot be
# deleted, so a rename strands the old context on every head that already
# carries it. Each name listed here is overwritten with a pointer to the live
# context on every evaluation, which supersedes the stale row and keeps a repo
# that still requires the old name satisfied. Comma-separated.
prCommentReviewGateRetiredStatusContexts: ""

# -- Pod spec knobs.
pod:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-- Webhook-triggered status deliveries have no heartbeat run or company row.
-- Keep those writes durable in the same outbox instead of logging and losing
-- a failed retired-context overwrite.
ALTER TABLE "github_commit_status_deliveries"
ALTER COLUMN "company_id" DROP NOT NULL;--> statement-breakpoint
ALTER TABLE "github_commit_status_deliveries"
ALTER COLUMN "source_run_id" DROP NOT NULL;
--> statement-breakpoint
ALTER TABLE "github_commit_status_deliveries"
ADD COLUMN IF NOT EXISTS "force_write" boolean DEFAULT false NOT NULL;
7 changes: 7 additions & 0 deletions packages/db/src/migrations/meta/_journal.json
Original file line number Diff line number Diff line change
Expand Up @@ -1618,6 +1618,13 @@
"when": 1788560000000,
"tag": "0238_heartbeat_runs_status_only_document_write_refused",
"breakpoints": true
},
{
"idx": 239,
"version": "7",
"when": 1788560060000,
"tag": "0239_github_status_webhook_outbox_provenance",
"breakpoints": true
}
]
}
11 changes: 4 additions & 7 deletions packages/db/src/schema/github_commit_status_deliveries.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { pgTable, uuid, text, timestamp, integer, jsonb, index, uniqueIndex } from "drizzle-orm/pg-core";
import { pgTable, uuid, text, timestamp, integer, jsonb, boolean, index, uniqueIndex } from "drizzle-orm/pg-core";
import { companies } from "./companies.js";
import { heartbeatRuns } from "./heartbeat_runs.js";

Expand All @@ -10,16 +10,13 @@ export const githubCommitStatusDeliveries = pgTable(
"github_commit_status_deliveries",
{
id: uuid("id").primaryKey().defaultRandom(),
companyId: uuid("company_id")
.notNull()
.references(() => companies.id),
sourceRunId: uuid("source_run_id")
.notNull()
.references(() => heartbeatRuns.id, { onDelete: "cascade" }),
companyId: uuid("company_id").references(() => companies.id),
sourceRunId: uuid("source_run_id").references(() => heartbeatRuns.id, { onDelete: "cascade" }),
repoFullName: text("repo_full_name").notNull(),
sha: text("sha").notNull(),
context: text("context").notNull(),
state: text("state").notNull().default("failure"),
forceWrite: boolean("force_write").notNull().default(false),
description: text("description").notNull(),
targetUrl: text("target_url"),
prNumber: integer("pr_number").notNull(),
Expand Down
Loading
Loading