Publish curated projectbrain source from 88fab8df1542019289e947f092c2b387e0825c60

This commit is contained in:
Public Source Publisher committed 2026-10-04 15:47:50 +00:00
1 parent 48e72d07e0
commit eca2891b07
45 files changed
+2697 -328

No files matched your search

+60 -4
View File
@@ -1,8 +1,10 @@
import { z } from "zod";
import type { AppEnv } from "../config/env.js";
import { prisma } from "../db/prisma.js";
import { configureAutonomy, getAutonomyState, importAutonomyRoadmap, normalizeAutonomyState, reportAutonomyWork, resumeAutonomy, retryAutonomyBlockerIfDue } from "../repositories/autonomyRepository.js";
import { configureAutonomy, getAutonomyState, importAutonomyRoadmap, normalizeAutonomyState, reorderAutonomyQueue, reportAutonomyWork, resetAutonomyQueueOrder, resumeAutonomy, retryAutonomyBlockerIfDue } from "../repositories/autonomyRepository.js";
import { claimAutonomyWork } from "../services/autonomyRuntimeControl.js";
import { createGiteaActivityRuntimeLoader } from "../services/activityRuntime.js";
import { evaluateRunnerClaimHealth } from "../services/runnerClaimHealth.js";
import { compactAutonomyState, recordAutonomyExecutorHeartbeat, touchAutonomyExecutorHeartbeat } from "../services/autonomyRuntime.js";
import { syncGitSources } from "../services/gitSourceSync.js";
import { reconcileRepositoryAutonomyRoadmap } from "../services/repositoryAutonomy.js";
@@ -60,6 +62,7 @@ const reportWithConflictRetry = async (
export const createProjectBrainMcpServer = (env: AppEnv, actor: string) => {
const server = createBaseProjectBrainMcpServer(env, actor);
const loadGiteaRuntime = createGiteaActivityRuntimeLoader(env);
server.registerTool("list_auto_mode_projects", {
title: "List ProjectBrain Auto Mode projects",
@@ -71,11 +74,15 @@ export const createProjectBrainMcpServer = (env: AppEnv, actor: string) => {
},
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
}, async ({ enabled_only, statuses, max_projects }) => {
const projects = await prisma.project.findMany({
const [projects, runnerRuntime] = await Promise.all([
prisma.project.findMany({
where: { deletedAt: null },
orderBy: { updatedAt: "desc" },
select: { slug: true, readableId: true, name: true, workspaceState: { select: { notesJson: true } } },
});
}),
loadGiteaRuntime(),
]);
const runnerClaimHealth = evaluateRunnerClaimHealth(runnerRuntime, { stallSeconds: env.PROJECTBRAIN_RUNNER_CLAIM_STALL_SECONDS });
const selectedStatuses = statuses?.length ? new Set(statuses) : undefined;
const rows = projects.flatMap((project) => {
const notes = asRecord(project.workspaceState?.notesJson);
@@ -117,7 +124,33 @@ export const createProjectBrainMcpServer = (env: AppEnv, actor: string) => {
retry_at: state.blocker?.retryAt,
}];
}).sort(compareAutoModeProjectRows).slice(0, max_projects);
return result({ projects: rows }, `${rows.length} Auto Mode project(s) matched. Claimable projects are ordered fairly by oldest last run (never-run projects first), so select the first row and keep processing claim_auto_work → execute → report_auto_work until that project's item or time budget is reached, work becomes busy or terminal, or user action is required.`);
const recoveryText = [
runnerClaimHealth.status === "stalled"
? "Runner claim-health is stalled; recovery ownership remains with the governed AppOps runner-fleet controller. Do not restart a still-running runner directly from ProjectBrain."
: "",
!runnerClaimHealth.runnerInventoryComplete
? "Runner inventory is unavailable; do not infer label compatibility, capacity, or polling stalls from missing runner data."
: "",
!runnerClaimHealth.coverage.complete
? `Runner claim-health scan is incomplete (${runnerClaimHealth.coverage.observed} queued job(s) observed of ${runnerClaimHealth.coverage.total ?? "unknown"}); do not infer the unobserved queue is healthy.`
: "",
].filter(Boolean).map((text) => ` ${text}`).join("");
return result({ projects: rows, runner_claim_health: runnerClaimHealth }, `${rows.length} Auto Mode project(s) matched. Claimable projects are ordered fairly by oldest last run (never-run projects first), so select the first row and keep processing claim_auto_work → execute → report_auto_work until that project's item or time budget is reached, work becomes busy or terminal, or user action is required.${recoveryText}`);
});
server.registerTool("get_runner_claim_health", {
title: "Get ProjectBrain runner claim health",
description: "Diagnose queued Gitea jobs against live runner labels and capacity. This surface is read-only: ProjectBrain distinguishes claim grace, capacity wait, label mismatch, polling stalls and incomplete runner inventory, while the governed AppOps runner-fleet controller remains the only recovery authority.",
inputSchema: {},
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
}, async () => {
const runtime = await loadGiteaRuntime();
const claimHealth = evaluateRunnerClaimHealth(runtime, { stallSeconds: env.PROJECTBRAIN_RUNNER_CLAIM_STALL_SECONDS });
const coverage = claimHealth.coverage.complete
? "queued-job scan complete"
: `queued-job scan incomplete (${claimHealth.coverage.observed} observed of ${claimHealth.coverage.total ?? "unknown"})`;
const inventory = claimHealth.runnerInventoryComplete ? "runner inventory complete" : "runner inventory unavailable; job diagnoses are unknown";
return result({ runner_claim_health: claimHealth }, `Runner claim health is ${claimHealth.status}; ${coverage}; ${inventory}; oldest runnable observed wait=${claimHealth.oldestWaitSeconds}s; oldest continuously claimable wait=${claimHealth.oldestClaimableWaitSeconds}s; recovery owner=${claimHealth.recoveryOwner}.`);
});
server.registerTool("heartbeat_auto_executor", {
@@ -237,6 +270,29 @@ export const createProjectBrainMcpServer = (env: AppEnv, actor: string) => {
return result({ state: state as unknown as Record<string, unknown> }, `Roadmap '${roadmap.title}' imported with ${roadmap.phases.length} phase(s) and ${roadmap.phases.reduce((count, phase) => count + phase.items.length, 0)} item(s).`);
});
server.registerTool("reorder_auto_queue", {
title: "Reorder ProjectBrain Auto Mode queue",
description: "Persist an explicit owner-defined order for all currently pending executable Auto Mode work items in one project. Supply the complete current item-id list in desired order. Running/completed/future work is not reorderable and dependency eligibility still wins at claim time.",
inputSchema: {
project_id: z.string().min(1),
item_ids: z.array(z.string().min(1)).max(500),
},
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
}, async ({ project_id, item_ids }) => {
const state = await reorderAutonomyQueue(project_id, item_ids, actor);
return result({ state: compactAutonomyState(state, { itemLimit: 25, eventLimit: 5 }) as unknown as Record<string, unknown> }, `Auto Mode queue reordered; ${item_ids.length} pending executable item(s) now have explicit owner order.`);
});
server.registerTool("reset_auto_queue_order", {
title: "Restore automatic ProjectBrain Auto Mode scheduling",
description: "Clear explicit manual ordering for one project's Auto Mode queue so the normal ProjectBrain scheduler again ranks ready work by scope, risk, dependencies, downstream impact and configured scheduling policy.",
inputSchema: { project_id: z.string().min(1) },
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
}, async ({ project_id }) => {
const state = await resetAutonomyQueueOrder(project_id, actor);
return result({ state: compactAutonomyState(state, { itemLimit: 25, eventLimit: 5 }) as unknown as Record<string, unknown> }, "Automatic Auto Mode scheduling order restored.");
});
server.registerTool("resume_auto_mode", {
title: "Resume blocked ProjectBrain Auto Mode",
description: "Clear the current Auto Mode blocker and make its blocked roadmap phase/item claimable again. The roadmap, completed phases and completed work are preserved; only blocker/retry state for the blocked work is reset.",
+3 -3
View File
@@ -3,7 +3,7 @@ import { z } from "zod";
import type { AppEnv } from "../config/env.js";
import { prisma } from "../db/prisma.js";
import { GiteaApiError } from "../integrations/gitea/client.js";
import { assertChatGptBranch, assertExpectedFileSha, assertFileSize, assertReadablePath, assertSuccessfulActionRuns, assertWritablePath, exactHeadActionRuns, findReusableDeliveryPullRequest } from "../integrations/gitea/policy.js";
import { assertChatGptBranch, assertExpectedFileSha, assertFileSize, assertReadablePath, assertSuccessfulActionRuns, assertWritablePath, exactHeadActionRuns, findReusableDeliveryPullRequest, successfulFullActionRun } from "../integrations/gitea/policy.js";
import { finishExternalOperation, getGiteaClient, listLinkedRepositories, markExternalOperationExecuting, prepareExternalOperation, recordMcpAudit, type LinkedRepository } from "../integrations/gitea/service.js";
import type { GiteaContent } from "../integrations/gitea/types.js";
import { assertFeatureDeliveryActionEvidence, canSyncFeatureDeliveryValidation, getFeatureDelivery, listFeatureDeliveries, openFeatureDeliveryPullRequest, reconcileFeatureDeliveryPullRequest, recordFeatureDeliveryActionValidation, recordFeatureDeliveryProgress, startFeatureDelivery, updateFeatureDelivery } from "../repositories/featureDeliveryRepository.js";
@@ -717,8 +717,8 @@ export const createProjectBrainMcpServer = (env: AppEnv, actor: string) => {
const branch = assertChatGptBranch(delivery.spec.branch, link!.defaultBranch);
const head = await client.getBranch(link!.owner, link!.repository, branch);
const response = await client.listActionRuns(link!.owner, link!.repository, { branch, headSha: head.commit.id, limit: 30 });
const verifiedRuns = assertSuccessfulActionRuns(response.workflow_runs, branch, head.commit.id);
const run = verifiedRuns.reduce((latest, candidate) => candidate.run_number > latest.run_number ? candidate : latest);
assertSuccessfulActionRuns(response.workflow_runs, branch, head.commit.id);
const run = successfulFullActionRun(response.workflow_runs, branch, head.commit.id);
const evidence = { provider: "gitea_actions" as const, runId: run.id, runNumber: run.run_number, url: run.html_url, workflowPath: run.path, headSha: run.head_sha, conclusion: "success" as const, verifiedAt: new Date().toISOString() };
return asResult({ run, delivery: await recordFeatureDeliveryActionValidation(project_id, delivery_id, evidence, actor) }, "Gitea Actions validation verified and persisted");
}, true));
+3 -3
View File
@@ -9,7 +9,7 @@ const definitions: SkillDefinition[] = [
{
name: "projectbrain-operator",
description: "Operate Auto Mode with ProjectBrain as controller and Gitea as the canonical repository execution and evidence surface.",
body: `# ProjectBrain operator\n\n1. Start with projectbrain.project.list and projectbrain.context.get when the ProjectBrain connector is available. Durable ProjectBrain state and repository planning files, not chat history, are the source of truth.\n2. ProjectBrain is the controller: it owns Auto policy, roadmap state, dependencies, recovery and human-attention decisions. Gitea is the only primary repository execution surface. ChatGPT may orchestrate and reason, but code changes must travel through governed Gitea branches, validation, pull requests and merge evidence. No OpenAI API key is required for this operating model.\n3. For implementation work, use the canonical branch returned as work.execution.branch. When working directly from repository planning truth without a ProjectBrain claim call, derive the same branch as projectbrain/auto/<normalized-work-id>: lowercase the durable task id and replace non alphanumeric, dot, underscore or hyphen runs with hyphens. The existence of that branch is the atomic execution claim. If it already exists, resume it; never create a competing branch for the same task.\n4. Load repository context from the current default branch, then resume or create the canonical non-default work branch. Use the Gitea workspace changeset flow for edits, run the narrowest managed validation profile and a full profile before merge when required, open or reuse the PR, confirm exact-head validation evidence, review the diff, and merge the exact validated head. Direct default-branch writes remain forbidden.\n5. An open PR is unfinished. A work item is implementation-complete only when its canonical PR is merged and the exact PR head has successful required Gitea Actions evidence. ProjectBrain then reconciles that evidence and downstream state back into Auto Mode.\n6. heartbeat_auto_executor, claim_auto_work and report_auto_work remain backward-compatible controller coordination tools. They are not the repository correctness authority. A missing or interrupted report_auto_work callback must never invalidate a valid Gitea branch/PR/validation/merge chain. When a compatibility lease is present, reuse it; after Gitea reconciliation a late report is an idempotent replay.\n7. For brainstorm or phase-review work, inspect ProjectBrain context plus repository roadmap/backlog, findings and evidence. Persist actionable implementation work into repository planning truth or ProjectBrain durable tasks, then execute resulting code work through the same canonical Gitea path. Do not invent routine approvals.\n8. Treat transient runner, Gitea, network and provider failures as retryable. Escalate to human attention only for credentials, policy authorization, destructive risk or a genuine product decision. Local models such as Ollama are optional helpers when explicitly permitted; they do not change the Gitea execution contract.\n`,
body: `# ProjectBrain operator\n\n1. Start with projectbrain.project.list and projectbrain.context.get when the ProjectBrain connector is available. Durable ProjectBrain state and repository planning files, not chat history, are the source of truth.\n2. ProjectBrain is the controller: it owns Auto policy, roadmap state, dependencies, recovery and human-attention decisions. Gitea is the only primary repository execution surface. ChatGPT may orchestrate and reason, but code changes must travel through governed Gitea branches, validation, pull requests and merge evidence. No OpenAI API key is required for this operating model.\n3. For implementation work, use the canonical branch returned as work.execution.branch. When working directly from repository planning truth without a ProjectBrain claim call, derive the same branch as projectbrain/auto/<normalized-work-id>: lowercase the durable task id and replace non alphanumeric, dot, underscore or hyphen runs with hyphens. The existence of that branch is the atomic execution claim. If it already exists, resume it; never create a competing branch for the same task.\n4. Load repository context from the current default branch, then resume or create the canonical non-default work branch. During implementation, use the coding workspace for the narrowest relevant tests after each behavioral slice and broader local regression at coherent checkpoints. Do not dispatch managed Gitea validation for every slice, subcommit, or small edit, and do not push solely to obtain runner evidence. Use a remote narrow profile only when the needed environment is unavailable locally. Dispatch one managed full profile when the exact branch HEAD is genuinely merge-ready; if that HEAD changes, treat the prior full result as stale and wait until the new HEAD is merge-ready before rerunning it. Open or reuse the PR, confirm exact-head full evidence, review the diff, and merge that exact validated head. Direct default-branch writes remain forbidden.\n5. An open PR is unfinished. A work item is implementation-complete only when its canonical PR is merged and the exact PR head has successful exact-head validation evidence from required Gitea Actions. ProjectBrain then reconciles that evidence and downstream state back into Auto Mode.\n6. heartbeat_auto_executor, claim_auto_work and report_auto_work remain backward-compatible controller coordination tools. They are not the repository correctness authority. A missing or interrupted report_auto_work callback must never invalidate a valid Gitea branch/PR/validation/merge chain. When a compatibility lease is present, reuse it; after Gitea reconciliation a late report is an idempotent replay.\n7. For brainstorm or phase-review work, inspect ProjectBrain context plus repository roadmap/backlog, findings and evidence. Persist actionable implementation work into repository planning truth or ProjectBrain durable tasks, then execute resulting code work through the same canonical Gitea path. Do not invent routine approvals.\n8. Treat transient runner, Gitea, network and provider failures as retryable. Escalate to human attention only for credentials, policy authorization, destructive risk or a genuine product decision. Local models such as Ollama are optional helpers when explicitly permitted; they do not change the Gitea execution contract.\n`,
},
{
name: "repository-bootstrap",
@@ -19,7 +19,7 @@ const definitions: SkillDefinition[] = [
{
name: "feature-delivery",
description: "Plan, implement, validate, review, and merge repository work through ProjectBrain's governed feature-delivery loop.",
body: `# Feature delivery\n\n1. Load projectbrain.delivery.get when resuming; durable state, not chat history, is the source of truth.\n2. Create a complete plan. ProjectBrain auto-authorizes owner-controlled MCP delivery plans, so continue directly to start or resume the valid isolated non-default delivery branch instead of asking for routine plan approval.\n3. Apply up to 25 create/update/delete operations atomically with projectbrain.delivery.changeset.apply. Refresh the branch head and file SHAs before every changeset and retry only after re-reading a conflict.\n4. Resume through gitea.workspace.status. Dispatch the narrowest fixed validation profile with gitea.workspace.run and use full before merge when supported. Respect pollAfterMs and poll only while terminal=false; after a transient runner failure, dispatch the same managed profile again instead of using the Gitea UI. Never stream logs into the browser unless diagnosing one selected failed job.\n5. Open or update the pull request, synchronize exact-head validation evidence, and inspect gitea.change.review.\n6. When completion/merge is already part of the user's instruction or an active Auto Mode roadmap, call projectbrain.delivery.merge with the exact head SHA after validation. It is idempotent across retries, rechecks Actions evidence, reconciles ProjectBrain and can clean the merged branch.\n7. Import a compact final execution summary as durable feedback and report changed paths, validation evidence, PR URL and merge state.\n`,
body: `# Feature delivery\n\n1. Load projectbrain.delivery.get when resuming; durable state, not chat history, is the source of truth.\n2. Create a complete plan. ProjectBrain auto-authorizes owner-controlled MCP delivery plans, so continue directly to start or resume the valid isolated non-default delivery branch instead of asking for routine plan approval.\n3. Apply up to 25 create/update/delete operations atomically with projectbrain.delivery.changeset.apply. Refresh the branch head and file SHAs before every changeset and retry only after re-reading a conflict.\n4. Resume through gitea.workspace.status. Prefer local workspace tests while code is changing: targeted checks per behavioral slice and a broader local regression at coherent checkpoints. Do not call gitea.workspace.run after every slice or subcommit and do not push only to obtain runner evidence. Use a narrow managed profile only for a genuine remote-environment gap or an explicit independent checkpoint. When the exact HEAD is merge-ready, dispatch full once; a later code change makes that evidence stale and requires a new full only when the new HEAD is again merge-ready. Respect pollAfterMs and poll only while terminal=false. Never stream logs into the browser unless diagnosing one selected failed job.\n5. Open or update the pull request, synchronize exact-head validation evidence, and inspect gitea.change.review.\n6. When completion/merge is already part of the user's instruction or an active Auto Mode roadmap, call projectbrain.delivery.merge with the exact head SHA after validation. It is idempotent across retries, rechecks Actions evidence, reconciles ProjectBrain and can clean the merged branch.\n7. Import a compact final execution summary as durable feedback and report changed paths, validation evidence, PR URL and merge state.\n`,
},
{
name: "portfolio-curator",
@@ -66,7 +66,7 @@ export const augmentProjectBrainInitialize = (payload: unknown) => {
const extensions = capabilities.extensions && typeof capabilities.extensions === "object" ? capabilities.extensions as Record<string, unknown> : {};
extensions[EXTENSION_ID] ??= {};
document.result.capabilities = { ...capabilities, extensions };
const autoInstruction = "ProjectBrain Auto Mode uses Gitea as its only primary repository execution surface. ProjectBrain remains the durable controller for roadmap, dependencies, recovery and human decisions; ChatGPT may orchestrate reasoning, but implementation changes must use governed Gitea branches, exact-head validation, pull requests and merge. For an Auto implementation item, use work.execution.branch when available or the deterministic projectbrain/auto/<normalized-work-id> branch when working directly from repository planning truth. Branch existence is the atomic claim: resume an existing branch instead of creating a duplicate. Completion is reconciled from the canonical PR, successful exact-head Gitea Actions evidence, its merge commit and downstream ProjectBrain state. heartbeat_auto_executor, claim_auto_work and report_auto_work are backward-compatible coordination/bookkeeping surfaces only; missing report_auto_work must never make a valid Gitea execution appear incomplete. Never write directly to the default branch, bypass validation, or create parallel branches for one durable work id.";
const autoInstruction = "ProjectBrain Auto Mode uses Gitea as its only primary repository execution surface. ProjectBrain remains the durable controller for roadmap, dependencies, recovery and human decisions; ChatGPT may orchestrate reasoning, but implementation changes must use governed Gitea branches, exact-head validation, pull requests and merge. For an Auto implementation item, use work.execution.branch when available or the deterministic projectbrain/auto/<normalized-work-id> branch when working directly from repository planning truth. Branch existence is the atomic claim: resume an existing branch instead of creating a duplicate. Completion is reconciled from the canonical PR, successful exact-head managed full validation evidence, its merge commit and downstream ProjectBrain state. Inner-loop development is local-first: managed runners are checkpoint and merge gates, not per-slice test workers. heartbeat_auto_executor, claim_auto_work and report_auto_work are backward-compatible coordination/bookkeeping surfaces only; missing report_auto_work must never make a valid Gitea execution appear incomplete. Never write directly to the default branch, bypass validation, or create parallel branches for one durable work id.";
document.result.instructions = document.result.instructions ? `${document.result.instructions}\n\n${autoInstruction}` : autoInstruction;
return document;
};