@mastra/factory 0.17.3-alpha.5 → 0.17.3-alpha.6
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/auth.d.ts.map +1 -1
- package/dist/auth.js +15 -4
- package/dist/auth.js.map +1 -1
- package/dist/boards/transition-policy.d.ts +3 -3
- package/dist/boards/transition-policy.d.ts.map +1 -1
- package/dist/boards/transition-policy.js.map +1 -1
- package/dist/boards/work-transition-policy.d.ts.map +1 -1
- package/dist/boards/work-transition-policy.js +3 -3
- package/dist/boards/work-transition-policy.js.map +1 -1
- package/dist/capabilities/intake.d.ts +2 -0
- package/dist/capabilities/intake.d.ts.map +1 -1
- package/dist/integrations/github/routes.d.ts.map +1 -1
- package/dist/integrations/github/routes.js +1 -0
- package/dist/integrations/github/routes.js.map +1 -1
- package/dist/integrations/gitlab/routes.d.ts.map +1 -1
- package/dist/integrations/gitlab/routes.js +1 -0
- package/dist/integrations/gitlab/routes.js.map +1 -1
- package/dist/integrations/linear/default-rules.d.ts +2 -1
- package/dist/integrations/linear/default-rules.d.ts.map +1 -1
- package/dist/integrations/linear/default-rules.js +1 -0
- package/dist/integrations/linear/default-rules.js.map +1 -1
- package/dist/integrations/linear/integration.d.ts.map +1 -1
- package/dist/integrations/linear/integration.js +2 -0
- package/dist/integrations/linear/integration.js.map +1 -1
- package/dist/integrations/linear/issue-reconciler.d.ts.map +1 -1
- package/dist/integrations/linear/issue-reconciler.js +3 -0
- package/dist/integrations/linear/issue-reconciler.js.map +1 -1
- package/dist/integrations/linear/routes.d.ts.map +1 -1
- package/dist/integrations/linear/routes.js +2 -1
- package/dist/integrations/linear/routes.js.map +1 -1
- package/dist/integrations/linear/rules.d.ts +1 -0
- package/dist/integrations/linear/rules.d.ts.map +1 -1
- package/dist/integrations/linear/rules.js.map +1 -1
- package/dist/integrations/slack/slack.d.ts +7 -7
- package/dist/integrations/slack/slack.d.ts.map +1 -1
- package/dist/integrations/slack/slack.js +13 -11
- package/dist/integrations/slack/slack.js.map +1 -1
- package/dist/platform-auth-host.d.ts +4 -0
- package/dist/platform-auth-host.d.ts.map +1 -0
- package/dist/platform-auth-host.js +18 -0
- package/dist/platform-auth-host.js.map +1 -0
- package/dist/routes/intake.d.ts.map +1 -1
- package/dist/routes/intake.js +15 -1
- package/dist/routes/intake.js.map +1 -1
- package/dist/routes/surface.d.ts +1 -1
- package/dist/routes/surface.d.ts.map +1 -1
- package/dist/routes/surface.js +47 -6
- package/dist/routes/surface.js.map +1 -1
- package/dist/routes/work-items.d.ts.map +1 -1
- package/dist/routes/work-items.js +6 -1
- package/dist/routes/work-items.js.map +1 -1
- package/dist/rules/dispatch-errors.d.ts.map +1 -1
- package/dist/rules/dispatch-errors.js +4 -0
- package/dist/rules/dispatch-errors.js.map +1 -1
- package/dist/rules/dispatcher.d.ts.map +1 -1
- package/dist/rules/dispatcher.js +3 -4
- package/dist/rules/dispatcher.js.map +1 -1
- package/dist/rules/processor.d.ts.map +1 -1
- package/dist/rules/processor.js +9 -1
- package/dist/rules/processor.js.map +1 -1
- package/dist/rules/start-coordinator.d.ts +7 -1
- package/dist/rules/start-coordinator.d.ts.map +1 -1
- package/dist/rules/start-coordinator.js +56 -2
- package/dist/rules/start-coordinator.js.map +1 -1
- package/dist/rules/transition-service.d.ts +4 -4
- package/dist/rules/transition-service.d.ts.map +1 -1
- package/dist/rules/transition-service.js +3 -2
- package/dist/rules/transition-service.js.map +1 -1
- package/dist/rules/types.d.ts +2 -0
- package/dist/rules/types.d.ts.map +1 -1
- package/dist/rules/types.js.map +1 -1
- package/dist/session/factory-session.d.ts +8 -4
- package/dist/session/factory-session.d.ts.map +1 -1
- package/dist/session/factory-session.js +4 -2
- package/dist/session/factory-session.js.map +1 -1
- package/dist/session/work-item-repository.d.ts +21 -0
- package/dist/session/work-item-repository.d.ts.map +1 -0
- package/dist/session/work-item-repository.js +91 -0
- package/dist/session/work-item-repository.js.map +1 -0
- package/dist/storage/domains/intake/base.d.ts +1 -0
- package/dist/storage/domains/intake/base.d.ts.map +1 -1
- package/dist/storage/domains/intake/base.js.map +1 -1
- package/dist/storage/domains/work-items/base.d.ts +2 -2
- package/dist/storage/domains/work-items/base.d.ts.map +1 -1
- package/dist/storage/domains/work-items/base.js +1 -0
- package/dist/storage/domains/work-items/base.js.map +1 -1
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js.map +1 -1
- package/factory-skills/factory-complete-issue/SKILL.md +4 -2
- package/factory-skills/factory-plan/SKILL.md +11 -0
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transition-service.js","names":["#configVersion","#boards","#storage","#timeoutMs","#onTerminalStage","#terminalCleanupTimeoutMs","#onAccepted","#autoApprovePlans","#audit","#commitRejection","#recordTransition","#evaluateAndCommit","#commit"],"sources":["../../src/rules/transition-service.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport { createBoardRegistry } from '../boards/index.js';\nimport type { BoardRegistry } from '../boards/index.js';\nimport { boardTransitionPolicyResultSchema, immutablePolicySnapshot } from '../boards/transition-policy.js';\nimport type { AuditActorProfileInput, AuditActorType, AuditContext } from '../storage/domains/audit/base.js';\nimport type { AuditRecorder } from '../storage/domains/audit/domain.js';\nimport { isAgentActor } from '../storage/domains/work-items/base.js';\nimport type { WorkItemRow, WorkItemsStorage } from '../storage/domains/work-items/base.js';\nimport { resolveFactoryStageRules } from './resolve.js';\nimport type {\n FactoryCommitDecision,\n FactoryRuleActor,\n FactoryRuleBoard,\n FactoryRuleCausalEntry,\n FactoryRuleRejectionCode,\n FactoryRuleStage,\n FactoryTriageType,\n FactoryStageRuleContext,\n FactoryTransitionResult,\n} from './types.js';\nimport {\n externallyAuthoredWorkItem,\n factoryRuleSourceForWorkItem,\n isFactoryRuleStage,\n workItemSource,\n} from './types.js';\nimport {\n MAX_FACTORY_RULE_CAUSAL_DEPTH,\n assertFactoryDecisionTarget,\n validateFactoryRuleDecision,\n validateFactoryRuleDecisions,\n} from './validation.js';\n\nconst RULE_TIMEOUT_MS = 5_000;\nconst MAX_REJECTION_REASON = 512;\n/** Longest a committed transition waits for terminal resource cleanup. Cleanup\n * reattaches remote sandboxes, so a hung provider call must not leave the\n * already-committed transition request pending; past this bound the cleanup\n * keeps running in the background as pure best-effort. */\nconst TERMINAL_CLEANUP_TIMEOUT_MS = 30_000;\n\nexport interface FactoryTransitionRequest {\n orgId: string;\n factoryProjectId: string;\n workItemId: string;\n /** Installed board id; the service rejects boards that are not installed. */\n board: string;\n stage: FactoryRuleStage;\n expectedRevision: number;\n actor: FactoryRuleActor;\n actorProfile?: AuditActorProfileInput;\n /** Where a browser request came from; rules and agents carry none. */\n context?: AuditContext;\n ingress: { type: 'human' | 'agent' | 'toolResult' | 'github' | 'rule'; identity: string; transitionId?: string };\n cause: string;\n causalChain?: readonly FactoryRuleCausalEntry[];\n /** Internal materialization path: evaluate only the destination onEnter leaf even when already at that stage. */\n initialEntry?: boolean;\n /** Re-runs the stage's entry rules when the item already holds that stage, to restart work the entry invalidated. */\n reenter?: boolean;\n /** Structured verdict required from a bound triage-agent terminal request. */\n triageType?: FactoryTriageType;\n}\n\nexport interface FactoryTransitionServiceOptions {\n configVersion: string;\n storage: WorkItemsStorage;\n boards?: BoardRegistry;\n /** Every commit, accepted or rejected, lands here as `stage_moved` / `transition_rejected` under the request's actor. */\n audit?: AuditRecorder;\n timeoutMs?: number;\n /**\n * Called after a transition commits into a phase the board declares\n * terminal — the point where the item's sessions stop receiving runs, so\n * resources they hold (e.g. sandboxes) can be released for reuse. Awaited,\n * but failures are swallowed: releasing resources must never break or roll\n * back the committed transition.\n */\n onTerminalStage?: (args: {\n orgId: string;\n factoryProjectId: string;\n workItemId: string;\n stage: FactoryRuleStage;\n revision: number;\n /** The actor that committed this terminal transition. Lets cleanup leave\n * the seat that drove its own transition (an agent tool call) untouched. */\n actor: FactoryRuleActor;\n }) => Promise<void> | void;\n /** Upper bound on how long a committed transition waits for\n * `onTerminalStage` before returning (default 30s). The cleanup continues\n * in the background past the bound. */\n terminalCleanupTimeoutMs?: number;\n /**\n * Called after a transition first records a person's acceptance of a\n * non-bug item (see `WorkItemRow.acceptedAt`). Fire-and-forget: failures\n * are swallowed, the committed transition never depends on it.\n */\n onAccepted?: (args: {\n orgId: string;\n factoryProjectId: string;\n workItemId: string;\n item: WorkItemRow;\n }) => Promise<void> | void;\n /**\n * Resolves whether a project auto-approves produced plans. Mirrors the\n * dispatcher's resolver so the two share a single authoritative predicate\n * (`plansPreapprovedAt` on the item, or this per-project setting). Unset means\n * off: a plan nobody armed for auto-advance is a plan a person must review.\n */\n autoApprovePlans?: (tenant: { orgId: string; factoryProjectId: string }) => Promise<boolean>;\n}\n\nfunction rejection(\n transitionId: string,\n itemId: string,\n code: FactoryRuleRejectionCode,\n reason: string,\n): FactoryTransitionResult {\n return { status: 'rejected', transitionId, itemId, code, reason: reason.slice(0, MAX_REJECTION_REASON) };\n}\n\nfunction actorId(actor: FactoryRuleActor): string {\n switch (actor.type) {\n case 'human':\n case 'system':\n return actor.id;\n case 'agent':\n return `agent:${actor.bindingId}`;\n case 'github':\n return `github:${actor.login}`;\n case 'gitlab':\n return `gitlab:${actor.username}`;\n }\n}\n\n// The dispatcher executes an agent-approved decision as a human actor so its consent carries; the trail still names the agent.\nexport function auditActorOf(actor: FactoryRuleActor): { actorId: string; actorType: AuditActorType } {\n const id = actorId(actor);\n switch (actor.type) {\n case 'github':\n case 'gitlab':\n return { actorId: id, actorType: 'human' };\n case 'human':\n return { actorId: id, actorType: isAgentActor(id) ? 'agent' : 'human' };\n default:\n return { actorId: id, actorType: actor.type };\n }\n}\n\nexport function currentStage(stages: readonly string[]): FactoryRuleStage | undefined {\n if (stages.length !== 1) return undefined;\n const stage = stages[0];\n return isFactoryRuleStage(stage) ? stage : undefined;\n}\n\ninterface TransitionConsentOptions {\n autonomy?: 'arm' | 'disarm';\n consentedBy?: string;\n accept?: boolean;\n triageType?: FactoryTriageType;\n}\n\n// Entering a resting lane disarms whoever rests it; only a person's move into a working lane arms.\nfunction transitionConsent(working: boolean, humanMove: boolean): 'arm' | 'disarm' | undefined {\n if (!working) return 'disarm';\n return humanMove ? 'arm' : undefined;\n}\n\n// An event arriving as data (GitHub, sweeps) never pre-approves the runs its transition queues.\nfunction bearsConsent(actor: FactoryRuleActor): boolean {\n return actor.type === 'human' || actor.type === 'agent';\n}\n\n// Rides the transition's own revision-checked commit, so a stale or rejected commit flips nothing.\nfunction consentEffect(\n request: FactoryTransitionRequest,\n working: boolean,\n humanMove: boolean,\n): TransitionConsentOptions {\n const autonomy = transitionConsent(working, humanMove);\n return bearsConsent(request.actor) ? { autonomy, consentedBy: actorId(request.actor) } : { autonomy };\n}\n\ntype RunStartDecision = Extract<FactoryCommitDecision, { type: 'invokeSkill' | 'sendMessage' }>;\n\nfunction startsRun(decision: FactoryCommitDecision): decision is RunStartDecision {\n return decision.type === 'invokeSkill' || (decision.type === 'sendMessage' && decision.prepareBinding === true);\n}\n\n// Answering a recorded run start, or the role's own mid-run agent, with a run would start a second one.\nfunction runAlreadyUnderway(request: FactoryTransitionRequest, decision: RunStartDecision): boolean {\n if (request.cause === 'run_start') return true;\n return request.actor.type === 'agent' && request.actor.role === decision.role;\n}\n\nfunction stageTransitionMessage(fromStage: FactoryRuleStage, toStage: FactoryRuleStage): string {\n return `This work was moved from the ${fromStage} stage to the ${toStage} stage.`;\n}\n\nfunction isTriageAgent(actor: FactoryRuleActor): actor is Extract<FactoryRuleActor, { type: 'agent' }> {\n return actor.type === 'agent' && actor.role === 'triage';\n}\n\nfunction isHumanTransition(request: FactoryTransitionRequest): boolean {\n return request.actor.type === 'human' && request.ingress.type === 'human';\n}\n\nfunction ruleFailure(error: unknown): { code: FactoryRuleRejectionCode; reason: string } {\n return {\n code: 'rule_error',\n reason: error instanceof Error ? `Factory rule failed: ${error.message}` : 'Factory rule failed.',\n };\n}\n\nasync function withRuleTimeout<T>(operation: Promise<T>, timeoutMs: number): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error('FACTORY_RULE_TIMEOUT')), timeoutMs);\n });\n try {\n return await Promise.race([operation, timeout]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\nexport class FactoryTransitionService {\n readonly #configVersion: string;\n readonly #boards: BoardRegistry;\n readonly #storage: WorkItemsStorage;\n readonly #timeoutMs: number;\n readonly #onTerminalStage: FactoryTransitionServiceOptions['onTerminalStage'];\n readonly #terminalCleanupTimeoutMs: number;\n readonly #onAccepted: FactoryTransitionServiceOptions['onAccepted'];\n readonly #autoApprovePlans: FactoryTransitionServiceOptions['autoApprovePlans'];\n readonly #audit: AuditRecorder | undefined;\n\n constructor(options: FactoryTransitionServiceOptions) {\n this.#configVersion = options.configVersion;\n this.#boards = options.boards ?? createBoardRegistry();\n this.#storage = options.storage;\n this.#audit = options.audit;\n this.#timeoutMs = options.timeoutMs ?? RULE_TIMEOUT_MS;\n this.#onTerminalStage = options.onTerminalStage;\n this.#onAccepted = options.onAccepted;\n this.#autoApprovePlans = options.autoApprovePlans;\n this.#terminalCleanupTimeoutMs = options.terminalCleanupTimeoutMs ?? TERMINAL_CLEANUP_TIMEOUT_MS;\n }\n\n get configVersion(): string {\n return this.#configVersion;\n }\n\n async transition(request: FactoryTransitionRequest): Promise<FactoryTransitionResult> {\n const replay = await this.#storage.getTransitionResultByIngress(\n request.orgId,\n request.factoryProjectId,\n request.ingress.identity,\n );\n if (replay) return replay as unknown as FactoryTransitionResult;\n\n const transitionId = request.ingress.transitionId ?? randomUUID();\n const item = await this.#storage.get({ orgId: request.orgId, id: request.workItemId });\n if (!item) {\n const rejection = await this.#commitRejection(\n request,\n transitionId,\n 'invalid_transition',\n 'Work item not found.',\n );\n await this.#recordTransition(request, undefined, rejection);\n return rejection;\n }\n const result = await this.#evaluateAndCommit(request, transitionId, item);\n await this.#recordTransition(request, item, result);\n return result;\n }\n\n /** A rejection can outlive its work item: the row still names the id the caller asked for. */\n async #recordTransition(\n request: FactoryTransitionRequest,\n item: WorkItemRow | undefined,\n result: FactoryTransitionResult,\n ): Promise<void> {\n if (!this.#audit) return;\n const from = item ? currentStage(item.stages) : undefined;\n if (result.status === 'accepted' && result.stage === from && !request.reenter) return;\n const outcome =\n result.status === 'accepted'\n ? { action: 'factory.work_item.stage_moved' as const, to: result.stage, revision: result.revision }\n : {\n action: 'factory.work_item.transition_rejected' as const,\n to: request.stage,\n code: result.code,\n reason: result.reason,\n };\n const { action, ...detail } = outcome;\n await this.#audit\n .record({\n orgId: request.orgId,\n factoryProjectId: request.factoryProjectId,\n ...auditActorOf(request.actor),\n actorProfile: request.actorProfile,\n ...(request.context ? { context: request.context } : {}),\n action,\n idempotencyKey: result.transitionId,\n targets: [{ type: 'work_item', id: item?.id ?? request.workItemId, ...(item ? { name: item.title } : {}) }],\n metadata: {\n transitionId: result.transitionId,\n ingressType: request.ingress.type,\n cause: request.cause,\n configVersion: this.#configVersion,\n ...(from ? { from } : {}),\n ...(request.reenter ? { reenter: true } : {}),\n ...detail,\n },\n })\n .catch(error => {\n console.warn(`[factory] audit failed for transition ${result.transitionId}:`, error);\n });\n }\n\n async #evaluateAndCommit(\n request: FactoryTransitionRequest,\n transitionId: string,\n item: WorkItemRow,\n ): Promise<FactoryTransitionResult> {\n if (request.causalChain && request.causalChain.length > MAX_FACTORY_RULE_CAUSAL_DEPTH) {\n return this.#commitRejection(\n request,\n transitionId,\n 'causal_depth_exceeded',\n 'Factory rule causal depth exceeded.',\n );\n }\n const itemSource = workItemSource(item.externalSource);\n const source = factoryRuleSourceForWorkItem(itemSource);\n const isPullRequest = source === 'pullRequest' || source === 'gitlabPullRequest';\n const legacyBoard = isPullRequest ? 'review' : 'work';\n if (item.board === null && !this.#boards.has(legacyBoard)) {\n return this.#commitRejection(\n request,\n transitionId,\n 'invalid_transition',\n 'This legacy work item has no assigned board. Assign an installed board and phase through the work-item PATCH endpoint before transitioning it.',\n );\n }\n const itemBoard = item.board ?? legacyBoard;\n if (request.board !== itemBoard) {\n return this.#commitRejection(\n request,\n transitionId,\n 'invalid_transition',\n `The work item belongs to board \"${itemBoard}\", not \"${request.board}\".`,\n );\n }\n if ((itemBoard === 'review' && !isPullRequest) || (itemBoard === 'work' && isPullRequest)) {\n return this.#commitRejection(\n request,\n transitionId,\n 'invalid_transition',\n 'The work item does not belong to the requested board.',\n );\n }\n const board = this.#boards.get(request.board);\n if (!board) {\n return this.#commitRejection(\n request,\n transitionId,\n 'invalid_transition',\n `Board \"${request.board}\" is not installed.`,\n );\n }\n const fromStage = item.stages.length === 1 ? item.stages[0] : undefined;\n if (!fromStage || !Object.prototype.hasOwnProperty.call(board.phases, fromStage)) {\n return this.#commitRejection(\n request,\n transitionId,\n 'invalid_transition',\n 'The work item does not have one canonical phase on the requested board.',\n );\n }\n if (\n !Object.prototype.hasOwnProperty.call(board.phases, request.stage) ||\n !board.allowsTransition(fromStage, request.stage)\n ) {\n const nextStages = [...new Set((board.transitions[fromStage] ?? []).map(transition => transition.to))];\n const nextStagesReason =\n nextStages.length > 0\n ? `Next stages declared from ${fromStage}: ${nextStages.join(', ')}.`\n : `No next stage is declared from ${fromStage}.`;\n return this.#commitRejection(\n request,\n transitionId,\n 'invalid_transition',\n `The ${board.title} board does not allow moving from ${fromStage} to ${request.stage}. ${nextStagesReason}`,\n );\n }\n\n // The coordinator's own self-move at run start would otherwise inject a second run's kickoff.\n const humanMove = request.actor.type === 'human' && fromStage !== request.stage && request.cause !== 'run_start';\n // The board, not the phase name, says whether a seat is engaged on either side of this move.\n const entersWorking = board.isWorking(request.stage);\n const seatRole = board.roleForPhase(request.stage);\n\n const contextBase = {\n tenant: { orgId: request.orgId, projectId: request.factoryProjectId },\n actor: request.actor,\n ingress: { type: request.ingress.type, id: request.ingress.identity },\n cause: request.cause,\n causalChain: request.causalChain ?? [],\n configVersion: this.#configVersion,\n item: {\n id: item.id,\n source: itemSource,\n sourceKey: item.externalSource\n ? `${item.externalSource.integrationId}:${item.externalSource.type}:${item.externalSource.externalId}`\n : null,\n parentWorkItemId: item.parentWorkItemId,\n title: item.title,\n url: item.externalSource?.url ?? null,\n stages: [...item.stages],\n acceptedAt: item.acceptedAt,\n metadata: item.metadata,\n },\n board: request.board,\n itemRevision: item.revision,\n source,\n fromStage,\n toStage: request.stage,\n } satisfies Omit<FactoryStageRuleContext, 'stage'>;\n\n let evaluation:\n | { outcome: 'accepted'; decisions: Record<string, unknown>[]; intents: TransitionConsentOptions }\n | { outcome: 'rejected'; code: string; reason: string };\n try {\n evaluation = await withRuleTimeout(\n (async () => {\n // Single authoritative plan-approval predicate, shared with the dispatcher's\n // `#plansAreAutoApproved`: a per-item preapproval, or the project setting.\n // Resolved inside the timed block so a resolver rejection surfaces as a\n // committed rule_error and a slow lookup is bounded by RULE_TIMEOUT_MS.\n const plansAutoApproved =\n item.plansPreapprovedAt != null ||\n (this.#autoApprovePlans\n ? await this.#autoApprovePlans({ orgId: request.orgId, factoryProjectId: request.factoryProjectId })\n : false);\n const policy = boardTransitionPolicyResultSchema.parse(\n await board.transitionPolicy?.(\n immutablePolicySnapshot({\n ...contextBase,\n item: { ...contextBase.item, triageType: item.triageType },\n initialEntry: request.initialEntry ?? false,\n reenter: request.reenter ?? false,\n isHumanTransition: isHumanTransition(request),\n plansAutoApproved,\n requestedTriageType: request.triageType,\n }),\n ),\n );\n if (policy?.type === 'reject') {\n return { outcome: 'rejected' as const, code: policy.code, reason: policy.reason };\n }\n if (\n policy?.triageType !== undefined &&\n (!isTriageAgent(request.actor) ||\n policy.triageType !== request.triageType ||\n (item.triageType !== null && item.triageType !== policy.triageType))\n ) {\n throw new Error('Board policy requested an unauthorized classification.');\n }\n if (policy?.accept && !isHumanTransition(request)) {\n throw new Error('Board policy requested unauthorized acceptance.');\n }\n // External content can steer a bound agent; board allowance cannot bypass this guard.\n if (\n request.actor.type === 'agent' &&\n !board.isWorking(fromStage) &&\n entersWorking &&\n externallyAuthoredWorkItem(item)\n ) {\n return {\n outcome: 'rejected' as const,\n code: 'approval_required',\n reason:\n 'This card comes from outside the write-access circle; a person must resume it from the Factory board.',\n };\n }\n const decisions: FactoryCommitDecision[] = [];\n for (const rule of resolveFactoryStageRules(this.#boards, {\n board: request.board,\n source,\n fromStage,\n toStage: request.stage,\n initialEntry: request.initialEntry,\n reenter: request.reenter,\n })) {\n const context: FactoryStageRuleContext = Object.freeze({\n ...contextBase,\n stage: rule.phase === 'exit' ? fromStage : request.stage,\n });\n const raw = await rule.handler(context);\n if (raw === undefined) continue;\n const decision = validateFactoryRuleDecision(raw, context.causalChain.length);\n if (decision.type === 'reject') {\n return { outcome: 'rejected' as const, code: decision.code, reason: decision.reason };\n }\n assertFactoryDecisionTarget(decision, this.#boards, itemBoard);\n if (startsRun(decision) && runAlreadyUnderway(request, decision)) continue;\n decisions.push(decision);\n }\n const validated = validateFactoryRuleDecisions(decisions);\n if (humanMove) {\n const message = stageTransitionMessage(fromStage, request.stage);\n const skill = validated.find(decision => decision.type === 'invokeSkill');\n if (skill) {\n skill.precedingMessage = message;\n } else {\n validated.unshift({\n type: 'sendMessage',\n idempotencyKey: `factory-stage:${transitionId}`,\n message,\n priority: 'urgent',\n idleBehavior: 'wake',\n // Parking a card says stop: no seat is right by construction, so\n // the notice goes to whichever session is live — or nobody.\n ...(entersWorking && seatRole !== undefined ? { role: seatRole, prepareBinding: true } : {}),\n });\n }\n }\n return {\n outcome: 'accepted' as const,\n intents: { triageType: policy?.triageType, accept: policy?.accept === true && !item.acceptedAt },\n decisions: validateFactoryRuleDecisions(validated) as unknown as Record<string, unknown>[],\n };\n })(),\n this.#timeoutMs,\n );\n } catch (error) {\n const failed =\n error instanceof Error && error.message === 'FACTORY_RULE_TIMEOUT'\n ? { code: 'timeout' as const, reason: 'Factory rule evaluation timed out.' }\n : ruleFailure(error);\n evaluation = { outcome: 'rejected', ...failed };\n }\n return this.#commit(\n request,\n transitionId,\n evaluation,\n evaluation.outcome === 'accepted'\n ? { ...consentEffect(request, entersWorking, humanMove), ...evaluation.intents }\n : {},\n );\n }\n\n async #commitRejection(\n request: FactoryTransitionRequest,\n transitionId: string,\n code: FactoryRuleRejectionCode,\n reason: string,\n ): Promise<FactoryTransitionResult> {\n return this.#commit(request, transitionId, {\n outcome: 'rejected',\n code,\n reason: reason.slice(0, MAX_REJECTION_REASON),\n });\n }\n\n async #commit(\n request: FactoryTransitionRequest,\n transitionId: string,\n evaluation:\n | { outcome: 'accepted'; decisions: Record<string, unknown>[] }\n | { outcome: 'rejected'; code: string; reason: string },\n options: TransitionConsentOptions = {},\n ): Promise<FactoryTransitionResult> {\n const committed = await this.#storage.commitTransition({\n autonomy: options.autonomy,\n consentedBy: options.consentedBy,\n ...(options.accept ? { accept: true } : {}),\n orgId: request.orgId,\n factoryProjectId: request.factoryProjectId,\n workItemId: request.workItemId,\n expectedRevision: request.expectedRevision,\n destinationStage: request.stage,\n actorId: actorId(request.actor),\n ingress: { identity: request.ingress.identity, triggerType: request.ingress.type, transitionId },\n configVersion: this.#configVersion,\n causalChain: [...(request.causalChain ?? [])],\n evaluation,\n ...(options.triageType ? { triageType: options.triageType } : {}),\n });\n if (committed.status === 'missing') {\n return rejection(transitionId, request.workItemId, 'invalid_transition', 'Work item not found.');\n }\n const result = committed.result as unknown as FactoryTransitionResult;\n if (\n this.#onAccepted &&\n options.accept &&\n committed.status === 'committed' &&\n result.status === 'accepted' &&\n committed.item?.acceptedAt\n ) {\n const item = committed.item;\n const onAccepted = this.#onAccepted;\n // Invoke inside the chain so a synchronous throw is isolated the same way an async rejection is.\n void Promise.resolve()\n .then(() =>\n onAccepted({\n orgId: request.orgId,\n factoryProjectId: request.factoryProjectId,\n workItemId: request.workItemId,\n item,\n }),\n )\n .catch(error => {\n console.warn(`[factory] acceptance hook failed for work item ${request.workItemId}:`, error);\n });\n }\n // Only an installed board's declaration releases resources; an unknown board or phase never does.\n if (\n this.#onTerminalStage &&\n result.status === 'accepted' &&\n this.#boards.get(request.board)?.isTerminal(result.stage) === true\n ) {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n const cleanup = Promise.resolve(\n this.#onTerminalStage({\n orgId: request.orgId,\n factoryProjectId: request.factoryProjectId,\n workItemId: request.workItemId,\n stage: result.stage,\n revision: result.revision,\n actor: request.actor,\n }),\n );\n // A late rejection after the timeout wins the race must not surface\n // as an unhandled rejection.\n cleanup.catch(() => {});\n await Promise.race([\n cleanup,\n new Promise<void>(resolve => {\n timer = setTimeout(resolve, this.#terminalCleanupTimeoutMs);\n }),\n ]);\n } catch {\n // Resource release is best-effort — never fail a committed transition.\n } finally {\n clearTimeout(timer);\n }\n }\n return result;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"transition-service.js","names":["#configVersion","#boards","#storage","#timeoutMs","#onTerminalStage","#terminalCleanupTimeoutMs","#onAccepted","#autoApprovePlans","#audit","#commitRejection","#recordTransition","#evaluateAndCommit","#commit"],"sources":["../../src/rules/transition-service.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport { createBoardRegistry } from '../boards/index.js';\nimport type { BoardRegistry } from '../boards/index.js';\nimport { boardTransitionPolicyResultSchema, immutablePolicySnapshot } from '../boards/transition-policy.js';\nimport type { AuditActorProfileInput, AuditActorType, AuditContext } from '../storage/domains/audit/base.js';\nimport type { AuditRecorder } from '../storage/domains/audit/domain.js';\nimport { isAgentActor } from '../storage/domains/work-items/base.js';\nimport type { WorkItemRow, WorkItemsStorage } from '../storage/domains/work-items/base.js';\nimport { resolveFactoryStageRules } from './resolve.js';\nimport type {\n FactoryCommitDecision,\n FactoryRuleActor,\n FactoryRuleBoard,\n FactoryRuleCausalEntry,\n FactoryRuleRejectionCode,\n FactoryRuleStage,\n FactoryTriageType,\n FactoryStageRuleContext,\n FactoryTransitionResult,\n} from './types.js';\nimport {\n externallyAuthoredWorkItem,\n factoryRuleSourceForWorkItem,\n isFactoryRuleStage,\n workItemSource,\n} from './types.js';\nimport {\n MAX_FACTORY_RULE_CAUSAL_DEPTH,\n assertFactoryDecisionTarget,\n validateFactoryRuleDecision,\n validateFactoryRuleDecisions,\n} from './validation.js';\n\nconst RULE_TIMEOUT_MS = 5_000;\nconst MAX_REJECTION_REASON = 512;\n/** Longest a committed transition waits for terminal resource cleanup. Cleanup\n * reattaches remote sandboxes, so a hung provider call must not leave the\n * already-committed transition request pending; past this bound the cleanup\n * keeps running in the background as pure best-effort. */\nconst TERMINAL_CLEANUP_TIMEOUT_MS = 30_000;\n\nexport interface FactoryTransitionRequest {\n orgId: string;\n factoryProjectId: string;\n workItemId: string;\n /** Installed board id; the service rejects boards that are not installed. */\n board: string;\n stage: FactoryRuleStage;\n expectedRevision: number;\n actor: FactoryRuleActor;\n actorProfile?: AuditActorProfileInput;\n /** Where a browser request came from; rules and agents carry none. */\n context?: AuditContext;\n ingress: { type: 'human' | 'agent' | 'toolResult' | 'github' | 'rule'; identity: string; transitionId?: string };\n cause: string;\n causalChain?: readonly FactoryRuleCausalEntry[];\n /** Internal materialization path: evaluate only the destination onEnter leaf even when already at that stage. */\n initialEntry?: boolean;\n /** Re-runs the stage's entry rules when the item already holds that stage, to restart work the entry invalidated. */\n reenter?: boolean;\n /** Structured verdict required from a bound triage-agent terminal request. */\n triageType?: FactoryTriageType;\n /** Internal proof that this move consumes an approved `submit_plan` result. */\n planApproved?: true;\n}\n\nexport interface FactoryTransitionServiceOptions {\n configVersion: string;\n storage: WorkItemsStorage;\n boards?: BoardRegistry;\n /** Every commit, accepted or rejected, lands here as `stage_moved` / `transition_rejected` under the request's actor. */\n audit?: AuditRecorder;\n timeoutMs?: number;\n /**\n * Called after a transition commits into a phase the board declares\n * terminal — the point where the item's sessions stop receiving runs, so\n * resources they hold (e.g. sandboxes) can be released for reuse. Awaited,\n * but failures are swallowed: releasing resources must never break or roll\n * back the committed transition.\n */\n onTerminalStage?: (args: {\n orgId: string;\n factoryProjectId: string;\n workItemId: string;\n stage: FactoryRuleStage;\n revision: number;\n /** The actor that committed this terminal transition. Lets cleanup leave\n * the seat that drove its own transition (an agent tool call) untouched. */\n actor: FactoryRuleActor;\n }) => Promise<void> | void;\n /** Upper bound on how long a committed transition waits for\n * `onTerminalStage` before returning (default 30s). The cleanup continues\n * in the background past the bound. */\n terminalCleanupTimeoutMs?: number;\n /**\n * Called after a transition first records a person's acceptance of a\n * non-bug item (see `WorkItemRow.acceptedAt`). Fire-and-forget: failures\n * are swallowed, the committed transition never depends on it.\n */\n onAccepted?: (args: {\n orgId: string;\n factoryProjectId: string;\n workItemId: string;\n item: WorkItemRow;\n }) => Promise<void> | void;\n /**\n * Resolves whether a project auto-approves produced plans. Unset means off:\n * a plan without explicit approval is a plan a person must review.\n */\n autoApprovePlans?: (tenant: { orgId: string; factoryProjectId: string }) => Promise<boolean>;\n}\n\nfunction rejection(\n transitionId: string,\n itemId: string,\n code: FactoryRuleRejectionCode,\n reason: string,\n): FactoryTransitionResult {\n return { status: 'rejected', transitionId, itemId, code, reason: reason.slice(0, MAX_REJECTION_REASON) };\n}\n\nfunction actorId(actor: FactoryRuleActor): string {\n switch (actor.type) {\n case 'human':\n case 'system':\n return actor.id;\n case 'agent':\n return `agent:${actor.bindingId}`;\n case 'github':\n return `github:${actor.login}`;\n case 'gitlab':\n return `gitlab:${actor.username}`;\n }\n}\n\n// The dispatcher executes an agent-approved decision as a human actor so its consent carries; the trail still names the agent.\nexport function auditActorOf(actor: FactoryRuleActor): { actorId: string; actorType: AuditActorType } {\n const id = actorId(actor);\n switch (actor.type) {\n case 'github':\n case 'gitlab':\n return { actorId: id, actorType: 'human' };\n case 'human':\n return { actorId: id, actorType: isAgentActor(id) ? 'agent' : 'human' };\n default:\n return { actorId: id, actorType: actor.type };\n }\n}\n\nexport function currentStage(stages: readonly string[]): FactoryRuleStage | undefined {\n if (stages.length !== 1) return undefined;\n const stage = stages[0];\n return isFactoryRuleStage(stage) ? stage : undefined;\n}\n\ninterface TransitionConsentOptions {\n autonomy?: 'arm' | 'disarm';\n consentedBy?: string;\n accept?: boolean;\n triageType?: FactoryTriageType;\n}\n\n// Entering a resting lane disarms whoever rests it; only a person's move into a working lane arms.\nfunction transitionConsent(working: boolean, humanMove: boolean): 'arm' | 'disarm' | undefined {\n if (!working) return 'disarm';\n return humanMove ? 'arm' : undefined;\n}\n\n// An event arriving as data (GitHub, sweeps) never pre-approves the runs its transition queues.\nfunction bearsConsent(actor: FactoryRuleActor): boolean {\n return actor.type === 'human' || actor.type === 'agent';\n}\n\n// Rides the transition's own revision-checked commit, so a stale or rejected commit flips nothing.\nfunction consentEffect(\n request: FactoryTransitionRequest,\n working: boolean,\n humanMove: boolean,\n): TransitionConsentOptions {\n const autonomy = transitionConsent(working, humanMove);\n return bearsConsent(request.actor) ? { autonomy, consentedBy: actorId(request.actor) } : { autonomy };\n}\n\ntype RunStartDecision = Extract<FactoryCommitDecision, { type: 'invokeSkill' | 'sendMessage' }>;\n\nfunction startsRun(decision: FactoryCommitDecision): decision is RunStartDecision {\n return decision.type === 'invokeSkill' || (decision.type === 'sendMessage' && decision.prepareBinding === true);\n}\n\n// Answering a recorded run start, or the role's own mid-run agent, with a run would start a second one.\nfunction runAlreadyUnderway(request: FactoryTransitionRequest, decision: RunStartDecision): boolean {\n if (request.cause === 'run_start') return true;\n return request.actor.type === 'agent' && request.actor.role === decision.role;\n}\n\nfunction stageTransitionMessage(fromStage: FactoryRuleStage, toStage: FactoryRuleStage): string {\n return `This work was moved from the ${fromStage} stage to the ${toStage} stage.`;\n}\n\nfunction isTriageAgent(actor: FactoryRuleActor): actor is Extract<FactoryRuleActor, { type: 'agent' }> {\n return actor.type === 'agent' && actor.role === 'triage';\n}\n\nfunction isHumanTransition(request: FactoryTransitionRequest): boolean {\n return request.actor.type === 'human' && request.ingress.type === 'human';\n}\n\nfunction ruleFailure(error: unknown): { code: FactoryRuleRejectionCode; reason: string } {\n return {\n code: 'rule_error',\n reason: error instanceof Error ? `Factory rule failed: ${error.message}` : 'Factory rule failed.',\n };\n}\n\nasync function withRuleTimeout<T>(operation: Promise<T>, timeoutMs: number): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error('FACTORY_RULE_TIMEOUT')), timeoutMs);\n });\n try {\n return await Promise.race([operation, timeout]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\nexport class FactoryTransitionService {\n readonly #configVersion: string;\n readonly #boards: BoardRegistry;\n readonly #storage: WorkItemsStorage;\n readonly #timeoutMs: number;\n readonly #onTerminalStage: FactoryTransitionServiceOptions['onTerminalStage'];\n readonly #terminalCleanupTimeoutMs: number;\n readonly #onAccepted: FactoryTransitionServiceOptions['onAccepted'];\n readonly #autoApprovePlans: FactoryTransitionServiceOptions['autoApprovePlans'];\n readonly #audit: AuditRecorder | undefined;\n\n constructor(options: FactoryTransitionServiceOptions) {\n this.#configVersion = options.configVersion;\n this.#boards = options.boards ?? createBoardRegistry();\n this.#storage = options.storage;\n this.#audit = options.audit;\n this.#timeoutMs = options.timeoutMs ?? RULE_TIMEOUT_MS;\n this.#onTerminalStage = options.onTerminalStage;\n this.#onAccepted = options.onAccepted;\n this.#autoApprovePlans = options.autoApprovePlans;\n this.#terminalCleanupTimeoutMs = options.terminalCleanupTimeoutMs ?? TERMINAL_CLEANUP_TIMEOUT_MS;\n }\n\n get configVersion(): string {\n return this.#configVersion;\n }\n\n async transition(request: FactoryTransitionRequest): Promise<FactoryTransitionResult> {\n const replay = await this.#storage.getTransitionResultByIngress(\n request.orgId,\n request.factoryProjectId,\n request.ingress.identity,\n );\n if (replay) return replay as unknown as FactoryTransitionResult;\n\n const transitionId = request.ingress.transitionId ?? randomUUID();\n const item = await this.#storage.get({ orgId: request.orgId, id: request.workItemId });\n if (!item) {\n const rejection = await this.#commitRejection(\n request,\n transitionId,\n 'invalid_transition',\n 'Work item not found.',\n );\n await this.#recordTransition(request, undefined, rejection);\n return rejection;\n }\n const result = await this.#evaluateAndCommit(request, transitionId, item);\n await this.#recordTransition(request, item, result);\n return result;\n }\n\n /** A rejection can outlive its work item: the row still names the id the caller asked for. */\n async #recordTransition(\n request: FactoryTransitionRequest,\n item: WorkItemRow | undefined,\n result: FactoryTransitionResult,\n ): Promise<void> {\n if (!this.#audit) return;\n const from = item ? currentStage(item.stages) : undefined;\n if (result.status === 'accepted' && result.stage === from && !request.reenter) return;\n const outcome =\n result.status === 'accepted'\n ? { action: 'factory.work_item.stage_moved' as const, to: result.stage, revision: result.revision }\n : {\n action: 'factory.work_item.transition_rejected' as const,\n to: request.stage,\n code: result.code,\n reason: result.reason,\n };\n const { action, ...detail } = outcome;\n await this.#audit\n .record({\n orgId: request.orgId,\n factoryProjectId: request.factoryProjectId,\n ...auditActorOf(request.actor),\n actorProfile: request.actorProfile,\n ...(request.context ? { context: request.context } : {}),\n action,\n idempotencyKey: result.transitionId,\n targets: [{ type: 'work_item', id: item?.id ?? request.workItemId, ...(item ? { name: item.title } : {}) }],\n metadata: {\n transitionId: result.transitionId,\n ingressType: request.ingress.type,\n cause: request.cause,\n configVersion: this.#configVersion,\n ...(from ? { from } : {}),\n ...(request.reenter ? { reenter: true } : {}),\n ...detail,\n },\n })\n .catch(error => {\n console.warn(`[factory] audit failed for transition ${result.transitionId}:`, error);\n });\n }\n\n async #evaluateAndCommit(\n request: FactoryTransitionRequest,\n transitionId: string,\n item: WorkItemRow,\n ): Promise<FactoryTransitionResult> {\n if (request.causalChain && request.causalChain.length > MAX_FACTORY_RULE_CAUSAL_DEPTH) {\n return this.#commitRejection(\n request,\n transitionId,\n 'causal_depth_exceeded',\n 'Factory rule causal depth exceeded.',\n );\n }\n const itemSource = workItemSource(item.externalSource);\n const source = factoryRuleSourceForWorkItem(itemSource);\n const isPullRequest = source === 'pullRequest' || source === 'gitlabPullRequest';\n const legacyBoard = isPullRequest ? 'review' : 'work';\n if (item.board === null && !this.#boards.has(legacyBoard)) {\n return this.#commitRejection(\n request,\n transitionId,\n 'invalid_transition',\n 'This legacy work item has no assigned board. Assign an installed board and phase through the work-item PATCH endpoint before transitioning it.',\n );\n }\n const itemBoard = item.board ?? legacyBoard;\n if (request.board !== itemBoard) {\n return this.#commitRejection(\n request,\n transitionId,\n 'invalid_transition',\n `The work item belongs to board \"${itemBoard}\", not \"${request.board}\".`,\n );\n }\n if ((itemBoard === 'review' && !isPullRequest) || (itemBoard === 'work' && isPullRequest)) {\n return this.#commitRejection(\n request,\n transitionId,\n 'invalid_transition',\n 'The work item does not belong to the requested board.',\n );\n }\n const board = this.#boards.get(request.board);\n if (!board) {\n return this.#commitRejection(\n request,\n transitionId,\n 'invalid_transition',\n `Board \"${request.board}\" is not installed.`,\n );\n }\n const fromStage = item.stages.length === 1 ? item.stages[0] : undefined;\n if (!fromStage || !Object.prototype.hasOwnProperty.call(board.phases, fromStage)) {\n return this.#commitRejection(\n request,\n transitionId,\n 'invalid_transition',\n 'The work item does not have one canonical phase on the requested board.',\n );\n }\n if (\n !Object.prototype.hasOwnProperty.call(board.phases, request.stage) ||\n !board.allowsTransition(fromStage, request.stage)\n ) {\n const nextStages = [...new Set((board.transitions[fromStage] ?? []).map(transition => transition.to))];\n const nextStagesReason =\n nextStages.length > 0\n ? `Next stages declared from ${fromStage}: ${nextStages.join(', ')}.`\n : `No next stage is declared from ${fromStage}.`;\n return this.#commitRejection(\n request,\n transitionId,\n 'invalid_transition',\n `The ${board.title} board does not allow moving from ${fromStage} to ${request.stage}. ${nextStagesReason}`,\n );\n }\n\n // The coordinator's own self-move at run start would otherwise inject a second run's kickoff.\n const humanMove = request.actor.type === 'human' && fromStage !== request.stage && request.cause !== 'run_start';\n // The board, not the phase name, says whether a seat is engaged on either side of this move.\n const entersWorking = board.isWorking(request.stage);\n const seatRole = board.roleForPhase(request.stage);\n\n const contextBase = {\n tenant: { orgId: request.orgId, projectId: request.factoryProjectId },\n actor: request.actor,\n ingress: { type: request.ingress.type, id: request.ingress.identity },\n cause: request.cause,\n causalChain: request.causalChain ?? [],\n configVersion: this.#configVersion,\n item: {\n id: item.id,\n source: itemSource,\n sourceKey: item.externalSource\n ? `${item.externalSource.integrationId}:${item.externalSource.type}:${item.externalSource.externalId}`\n : null,\n parentWorkItemId: item.parentWorkItemId,\n title: item.title,\n url: item.externalSource?.url ?? null,\n stages: [...item.stages],\n acceptedAt: item.acceptedAt,\n metadata: item.metadata,\n },\n board: request.board,\n itemRevision: item.revision,\n source,\n fromStage,\n toStage: request.stage,\n } satisfies Omit<FactoryStageRuleContext, 'stage'>;\n\n let evaluation:\n | { outcome: 'accepted'; decisions: Record<string, unknown>[]; intents: TransitionConsentOptions }\n | { outcome: 'rejected'; code: string; reason: string };\n try {\n evaluation = await withRuleTimeout(\n (async () => {\n // Resolve the project switch inside the timed block so a resolver rejection\n // surfaces as a committed rule_error and a slow lookup is bounded.\n const plansAutoApproved = this.#autoApprovePlans\n ? await this.#autoApprovePlans({ orgId: request.orgId, factoryProjectId: request.factoryProjectId })\n : false;\n const policy = boardTransitionPolicyResultSchema.parse(\n await board.transitionPolicy?.(\n immutablePolicySnapshot({\n ...contextBase,\n item: { ...contextBase.item, triageType: item.triageType },\n initialEntry: request.initialEntry ?? false,\n reenter: request.reenter ?? false,\n isHumanTransition: isHumanTransition(request),\n plansAutoApproved,\n planApproved: request.planApproved === true,\n requestedTriageType: request.triageType,\n }),\n ),\n );\n if (policy?.type === 'reject') {\n return { outcome: 'rejected' as const, code: policy.code, reason: policy.reason };\n }\n if (\n policy?.triageType !== undefined &&\n (!isTriageAgent(request.actor) ||\n policy.triageType !== request.triageType ||\n (item.triageType !== null && item.triageType !== policy.triageType))\n ) {\n throw new Error('Board policy requested an unauthorized classification.');\n }\n if (policy?.accept && !isHumanTransition(request)) {\n throw new Error('Board policy requested unauthorized acceptance.');\n }\n // External content can steer a bound agent; board allowance cannot bypass this guard.\n if (\n request.actor.type === 'agent' &&\n !board.isWorking(fromStage) &&\n entersWorking &&\n externallyAuthoredWorkItem(item)\n ) {\n return {\n outcome: 'rejected' as const,\n code: 'approval_required',\n reason:\n 'This card comes from outside the write-access circle; a person must resume it from the Factory board.',\n };\n }\n const decisions: FactoryCommitDecision[] = [];\n for (const rule of resolveFactoryStageRules(this.#boards, {\n board: request.board,\n source,\n fromStage,\n toStage: request.stage,\n initialEntry: request.initialEntry,\n reenter: request.reenter,\n })) {\n const context: FactoryStageRuleContext = Object.freeze({\n ...contextBase,\n stage: rule.phase === 'exit' ? fromStage : request.stage,\n });\n const raw = await rule.handler(context);\n if (raw === undefined) continue;\n const decision = validateFactoryRuleDecision(raw, context.causalChain.length);\n if (decision.type === 'reject') {\n return { outcome: 'rejected' as const, code: decision.code, reason: decision.reason };\n }\n assertFactoryDecisionTarget(decision, this.#boards, itemBoard);\n if (startsRun(decision) && runAlreadyUnderway(request, decision)) continue;\n decisions.push(decision);\n }\n const validated = validateFactoryRuleDecisions(decisions);\n if (humanMove) {\n const message = stageTransitionMessage(fromStage, request.stage);\n const skill = validated.find(decision => decision.type === 'invokeSkill');\n if (skill) {\n skill.precedingMessage = message;\n } else {\n validated.unshift({\n type: 'sendMessage',\n idempotencyKey: `factory-stage:${transitionId}`,\n message,\n priority: 'urgent',\n idleBehavior: 'wake',\n // Parking a card says stop: no seat is right by construction, so\n // the notice goes to whichever session is live — or nobody.\n ...(entersWorking && seatRole !== undefined ? { role: seatRole, prepareBinding: true } : {}),\n });\n }\n }\n return {\n outcome: 'accepted' as const,\n intents: { triageType: policy?.triageType, accept: policy?.accept === true && !item.acceptedAt },\n decisions: validateFactoryRuleDecisions(validated) as unknown as Record<string, unknown>[],\n };\n })(),\n this.#timeoutMs,\n );\n } catch (error) {\n const failed =\n error instanceof Error && error.message === 'FACTORY_RULE_TIMEOUT'\n ? { code: 'timeout' as const, reason: 'Factory rule evaluation timed out.' }\n : ruleFailure(error);\n evaluation = { outcome: 'rejected', ...failed };\n }\n return this.#commit(\n request,\n transitionId,\n evaluation,\n evaluation.outcome === 'accepted'\n ? { ...consentEffect(request, entersWorking, humanMove), ...evaluation.intents }\n : {},\n );\n }\n\n async #commitRejection(\n request: FactoryTransitionRequest,\n transitionId: string,\n code: FactoryRuleRejectionCode,\n reason: string,\n ): Promise<FactoryTransitionResult> {\n return this.#commit(request, transitionId, {\n outcome: 'rejected',\n code,\n reason: reason.slice(0, MAX_REJECTION_REASON),\n });\n }\n\n async #commit(\n request: FactoryTransitionRequest,\n transitionId: string,\n evaluation:\n | { outcome: 'accepted'; decisions: Record<string, unknown>[] }\n | { outcome: 'rejected'; code: string; reason: string },\n options: TransitionConsentOptions = {},\n ): Promise<FactoryTransitionResult> {\n const committed = await this.#storage.commitTransition({\n autonomy: options.autonomy,\n consentedBy: options.consentedBy,\n ...(options.accept ? { accept: true } : {}),\n orgId: request.orgId,\n factoryProjectId: request.factoryProjectId,\n workItemId: request.workItemId,\n expectedRevision: request.expectedRevision,\n destinationStage: request.stage,\n actorId: actorId(request.actor),\n ingress: { identity: request.ingress.identity, triggerType: request.ingress.type, transitionId },\n configVersion: this.#configVersion,\n causalChain: [...(request.causalChain ?? [])],\n evaluation,\n ...(options.triageType ? { triageType: options.triageType } : {}),\n });\n if (committed.status === 'missing') {\n return rejection(transitionId, request.workItemId, 'invalid_transition', 'Work item not found.');\n }\n const result = committed.result as unknown as FactoryTransitionResult;\n if (\n this.#onAccepted &&\n options.accept &&\n committed.status === 'committed' &&\n result.status === 'accepted' &&\n committed.item?.acceptedAt\n ) {\n const item = committed.item;\n const onAccepted = this.#onAccepted;\n // Invoke inside the chain so a synchronous throw is isolated the same way an async rejection is.\n void Promise.resolve()\n .then(() =>\n onAccepted({\n orgId: request.orgId,\n factoryProjectId: request.factoryProjectId,\n workItemId: request.workItemId,\n item,\n }),\n )\n .catch(error => {\n console.warn(`[factory] acceptance hook failed for work item ${request.workItemId}:`, error);\n });\n }\n // Only an installed board's declaration releases resources; an unknown board or phase never does.\n if (\n this.#onTerminalStage &&\n result.status === 'accepted' &&\n this.#boards.get(request.board)?.isTerminal(result.stage) === true\n ) {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n const cleanup = Promise.resolve(\n this.#onTerminalStage({\n orgId: request.orgId,\n factoryProjectId: request.factoryProjectId,\n workItemId: request.workItemId,\n stage: result.stage,\n revision: result.revision,\n actor: request.actor,\n }),\n );\n // A late rejection after the timeout wins the race must not surface\n // as an unhandled rejection.\n cleanup.catch(() => {});\n await Promise.race([\n cleanup,\n new Promise<void>(resolve => {\n timer = setTimeout(resolve, this.#terminalCleanupTimeoutMs);\n }),\n ]);\n } catch {\n // Resource release is best-effort — never fail a committed transition.\n } finally {\n clearTimeout(timer);\n }\n }\n return result;\n }\n}\n"],"mappings":"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"}
|
package/dist/rules/types.d.ts
CHANGED
|
@@ -303,6 +303,8 @@ export interface FactoryLinearRuleContext extends FactoryRuleContextBase {
|
|
|
303
303
|
labels: readonly string[];
|
|
304
304
|
createdAt: string;
|
|
305
305
|
updatedAt: string;
|
|
306
|
+
sourceId?: string | null;
|
|
307
|
+
projectId?: string | null;
|
|
306
308
|
};
|
|
307
309
|
}
|
|
308
310
|
export interface FactoryJiraRuleContext extends FactoryRuleContextBase {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/rules/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/rules/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAEpF,MAAM,MAAM,cAAc,GACtB,cAAc,GACd,WAAW,GACX,cAAc,GACd,WAAW,GACX,cAAc,GACd,YAAY,GACZ,sBAAsB,GACtB,QAAQ,CAAC;AAEb,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,MAAM,EACjB,GAAG,CAAC,EAAE,MAAM,GACX,sBAAsB,CAkBxB;AAED,oGAAoG;AACpG,eAAO,MAAM,oBAAoB,2BAA2B,CAAC;AAC7D,eAAO,MAAM,kBAAkB,yBAAyB,CAAC;AAIzD,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAClC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;CACnC,GAAG,OAAO,CAQV;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,sBAAsB,GAAG,IAAI,GAAG,cAAc,CAWpF;AAID,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CAAE,GAAG,OAAO,CAI9G;AAGD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CAAE,GAAG,OAAO,CAE/G;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAC/C,cAAc,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC9C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC1C,GAAG,OAAO,CAEV;AAED,eAAO,MAAM,mBAAmB,oFAAqF,CAAC;AACtH,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAIpF,eAAO,MAAM,mBAAmB;;;;;CAKqB,CAAC;AACtD,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,mBAAmB,CAAC;AAE3D,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,WAAW,CAEjE;AAED,eAAO,MAAM,oBAAoB,qJAYvB,CAAC;AACX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,iBAAiB,CAE9E;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,gBAAgB,CAE5E;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,gBAAgB,GAAG,SAAS,CAGxF;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAG7E;AAED,yFAAyF;AACzF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAE1E;AAID,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAE7E;AAED,eAAO,MAAM,mBAAmB,6BAA8B,CAAC;AAC/D,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEpF,eAAO,MAAM,oBAAoB,mIASvB,CAAC;AACX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,eAAO,MAAM,qBAAqB,0SAcxB,CAAC;AACX,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5E,eAAO,MAAM,qBAAqB,6LAUxB,CAAC;AACX,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5E,eAAO,MAAM,qBAAqB,2CAA4C,CAAC;AAC/E,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5E,eAAO,MAAM,mBAAmB,2CAA4C,CAAC;AAC7E,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE,eAAO,MAAM,yBAAyB,iDAAkD,CAAC;AACzF,MAAM,MAAM,0BAA0B,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpF,MAAM,MAAM,oBAAoB,GAC5B,IAAI,GACJ,OAAO,GACP,MAAM,GACN,MAAM,GACN,oBAAoB,EAAE,GACtB;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,CAAA;CAAE,CAAC;AAE5C,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,cAAc,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,qFAAqF;IACrF,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,eAAe,EAAE,OAAO,CAAA;CAAE,GAC7E;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,eAAe,EAAE,OAAO,CAAA;CAAE,GAChF;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnC,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,YAAY,GAAG,MAAM,CAAC;IACzG,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,KAAK,EAAE,gBAAgB,CAAC;IACxB,OAAO,EAAE,0BAA0B,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,SAAS,sBAAsB,EAAE,CAAC;IAC/C,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,uBAAwB,SAAQ,sBAAsB;IACrE,IAAI,EAAE,sBAAsB,CAAC;IAC7B,KAAK,EAAE,gBAAgB,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,uBAAwB,SAAQ,uBAAuB;IACtE,MAAM,EAAE,iBAAiB,CAAC;IAC1B,KAAK,EAAE,gBAAgB,CAAC;IACxB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,OAAO,EAAE,gBAAgB,CAAC;CAC3B;AAED,MAAM,WAAW,4BAA6B,SAAQ,uBAAuB;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE;QACN,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;QAC5B,KAAK,EAAE,oBAAoB,CAAC;KAC7B,CAAC;CACH;AAED,MAAM,WAAW,wBAAyB,SAAQ,sBAAsB;IACtE,IAAI,CAAC,EAAE,sBAAsB,CAAC;IAC9B,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC;;;;;;;;OAQG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,KAAK,EAAE,sBAAsB,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/B,UAAU,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,KAAK,CAAC,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;QAC1B,uEAAuE;QACvE,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,WAAW,CAAC,EAAE;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC;IAChD,YAAY,CAAC,EAAE;QACb,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,WAAW,CAAC,EAAE;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC;QACzB,KAAK,EAAE,OAAO,CAAC;QACf,MAAM,EAAE,OAAO,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;QAC9B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,eAAe,EAAE,OAAO,CAAC;QACzB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,mFAAmF;IACnF,aAAa,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,OAAO,CAAA;KAAE,CAAC;IAC/D,qEAAqE;IACrE,aAAa,CAAC,EAAE;QAAE,OAAO,EAAE,QAAQ,GAAG,WAAW,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACpE,gFAAgF;IAChF,MAAM,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACrD;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,wBAAyB,SAAQ,sBAAsB;IACtE,IAAI,CAAC,EAAE,sBAAsB,CAAC;IAC9B,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,KAAK,EAAE,sBAAsB,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/B,UAAU,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D,KAAK,CAAC,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;QAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,EAAE,OAAO,CAAC;KACxB,CAAC;IACF,IAAI,CAAC,EAAE;QACL,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,YAAY,CAAC,EAAE;QACb,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC;QACzB,KAAK,EAAE,OAAO,CAAC;QACf,MAAM,EAAE,OAAO,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,EAAE,OAAO,CAAC;QACvB,eAAe,EAAE,OAAO,CAAC;QACzB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,MAAM,WAAW,wBAAyB,SAAQ,sBAAsB;IACtE,IAAI,CAAC,EAAE,sBAAsB,CAAC;IAC9B,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6FAA6F;IAC7F,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,KAAK,EAAE,sBAAsB,CAAC;IAC9B,KAAK,EAAE;QACL,EAAE,EAAE,MAAM,CAAC;QACX,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;QACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;QAC1B,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC3B,CAAC;CACH;AAED,MAAM,WAAW,sBAAuB,SAAQ,sBAAsB;IACpE,IAAI,CAAC,EAAE,sBAAsB,CAAC;IAC9B,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6FAA6F;IAC7F,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,KAAK,EAAE,oBAAoB,CAAC;IAC5B,KAAK,EAAE;QACL,yGAAyG;QACzG,EAAE,EAAE,MAAM,CAAC;QACX,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;QACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;QAC1B,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,4BAA6B,SAAQ,sBAAsB;IAC1E,IAAI,CAAC,EAAE,sBAAsB,CAAC;IAC9B,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iGAAiG;IACjG,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,KAAK,EAAE,0BAA0B,CAAC;IAClC,KAAK,EAAE;QACL,oGAAoG;QACpG,EAAE,EAAE,MAAM,CAAC;QACX,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;QACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,2EAA2E;QAC3E,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;QAC1B,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,MAAM,kBAAkB,CAAC,QAAQ,IAAI,CACzC,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,KACxB,mBAAmB,GAAG,IAAI,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;AAEtE,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,kBAAkB,CAAC,uBAAuB,CAAC,CAAC;IACtD,MAAM,CAAC,EAAE,kBAAkB,CAAC,uBAAuB,CAAC,CAAC;CACtD;AAED,MAAM,MAAM,wBAAwB,GAChC,WAAW,GACX,oBAAoB,GACpB,iBAAiB,GACjB,OAAO,GACP,SAAS,GACT,YAAY,GACZ,uBAAuB,GACvB,qBAAqB,GACrB,mBAAmB,CAAC;AAExB,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,wBAAwB,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,yBAAyB;IACjC,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,yBAA0B,SAAQ,yBAAyB;IAC1E,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,gBAAgB,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB;;;;OAIG;IACH,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,mCAAoC,SAAQ,yBAAyB;IACpF,IAAI,EAAE,sBAAsB,CAAC;IAC7B,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,cAAc,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,KAAK,EAAE,gBAAgB,CAAC;IACxB;;;;;;;;;;OAUG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;CACjD;AAED,UAAU,8BAA+B,SAAQ,yBAAyB;IACxE,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,MAAM,MAAM,0BAA0B,GAAG,8BAA8B,GACrE,CACI;IACE,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,KAAK,CAAC;IACf;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GACD;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,KAAK,CAAC;IAAC,MAAM,CAAC,EAAE,KAAK,CAAA;CAAE,CACxD,CAAC;AAEJ,MAAM,WAAW,0BAA2B,SAAQ,yBAAyB;IAC3E,IAAI,EAAE,aAAa,CAAC;IACpB,iGAAiG;IACjG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;IACxC,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAClC,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAsB,SAAQ,yBAAyB;IACtE,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;CACtC;AAED,MAAM,MAAM,qBAAqB,GAC7B,yBAAyB,GACzB,mCAAmC,GACnC,0BAA0B,GAC1B,0BAA0B,GAC1B,qBAAqB,CAAC;AAE1B,MAAM,MAAM,mBAAmB,GAAG,yBAAyB,GAAG,qBAAqB,CAAC;AAEpF,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,UAAU,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,gBAAgB,CAAC;IACxB,SAAS,EAAE,qBAAqB,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,UAAU,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,wBAAwB,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,uBAAuB,GAAG,+BAA+B,GAAG,+BAA+B,CAAC;AAExG,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,cAAc,GAAG,iBAAiB,CAmBtF"}
|
package/dist/rules/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../../src/rules/types.ts"],"sourcesContent":["import type { ExternalWorkItemSource } from '../storage/domains/work-items/base.js';\n\nexport type WorkItemSource =\n | 'github-issue'\n | 'github-pr'\n | 'gitlab-issue'\n | 'gitlab-pr'\n | 'linear-issue'\n | 'jira-issue'\n | 'incidentio-follow-up'\n | 'manual';\n\nexport function externalSourceForWorkItem(\n source: WorkItemSource,\n sourceKey: string,\n url?: string,\n): ExternalWorkItemSource {\n const [integrationId, type] =\n source === 'github-pr'\n ? ['github', 'pull-request']\n : source === 'github-issue'\n ? ['github', 'issue']\n : source === 'gitlab-pr'\n ? ['gitlab', 'pull-request']\n : source === 'gitlab-issue'\n ? ['gitlab', 'issue']\n : source === 'linear-issue'\n ? ['linear', 'issue']\n : source === 'jira-issue'\n ? ['jira', 'issue']\n : source === 'incidentio-follow-up'\n ? ['incidentio', 'issue']\n : ['factory', 'manual'];\n return { integrationId, type, externalId: sourceKey, ...(url ? { url } : {}) };\n}\n\n/** The source label that holds an issue at rest until a maintainer decides; compared lowercased. */\nexport const NEEDS_APPROVAL_LABEL = 'status: needs approval';\nexport const AUTO_TRIAGED_LABEL = 'status: auto-triaged';\n\n// The label only holds a card at rest: once a person accepted it, or it sits in a working\n// lane only a person could have moved it into, the label is stale until the source catches up.\nexport function needsApproval(item: {\n metadata: Record<string, unknown> | null;\n stages?: readonly string[];\n acceptedAt?: Date | string | null;\n}): boolean {\n const labels = item.metadata?.labels;\n if (!Array.isArray(labels)) return false;\n return (\n labels.some(label => typeof label === 'string' && label.toLowerCase() === NEEDS_APPROVAL_LABEL) &&\n !item.acceptedAt &&\n (item.stages ?? ['intake']).every(stage => stage === 'intake' || stage === 'triage')\n );\n}\n\nexport function workItemSource(source: ExternalWorkItemSource | null): WorkItemSource {\n if (!source) return 'manual';\n if (source.integrationId === 'linear') return 'linear-issue';\n if (source.integrationId === 'gitlab') return source.type === 'pull-request' ? 'gitlab-pr' : 'gitlab-issue';\n if (source.integrationId === 'jira') return 'jira-issue';\n if (source.integrationId === 'incidentio') return 'incidentio-follow-up';\n // Only GitHub, GitLab, Linear, Jira, and incident.io have provider-specific\n // rules; anything else (a Slack thread, say) is a plain work item, not a\n // mislabeled GitHub issue.\n if (source.integrationId !== 'github') return 'manual';\n return source.type === 'pull-request' ? 'github-pr' : 'github-issue';\n}\n\n// Authored outside the write-access circle: a missing trust stamp fails closed until\n// the reconcile sweep backfills it, and Factory's own PRs pass through `factoryAuthored`.\nexport function externallyAuthored(item: { source: string; metadata: Record<string, unknown> | null }): boolean {\n if (!['github-pr', 'github-issue', 'gitlab-pr', 'gitlab-issue'].includes(item.source)) return false;\n if (item.metadata?.factoryAuthored === true) return false;\n return item.metadata?.authorTrusted !== true;\n}\n\n// The board mark claims only what GitHub answered: a missing stamp is silence, not an outside contribution.\nexport function knownExternalAuthor(item: { source: string; metadata: Record<string, unknown> | null }): boolean {\n return externallyAuthored(item) && item.metadata?.authorTrusted === false;\n}\n\nexport function externallyAuthoredWorkItem(item: {\n externalSource: ExternalWorkItemSource | null;\n metadata: Record<string, unknown> | null;\n}): boolean {\n return externallyAuthored({ source: workItemSource(item.externalSource), metadata: item.metadata });\n}\n\nexport const FACTORY_RULE_STAGES = ['intake', 'triage', 'planning', 'execute', 'review', 'done', 'canceled'] as const;\nexport type FactoryRuleStage = (typeof FACTORY_RULE_STAGES)[number] | (string & {});\n\n// Each role and the working stage its run holds the card in. Key order is the\n// seat pipeline order — Resume depth derives from it.\nexport const FACTORY_ROLE_STAGES = {\n triage: 'triage',\n plan: 'planning',\n work: 'execute',\n review: 'review',\n} as const satisfies Record<string, FactoryRuleStage>;\nexport type FactoryRole = keyof typeof FACTORY_ROLE_STAGES;\n\nexport function isFactoryRole(value: string): value is FactoryRole {\n return value in FACTORY_ROLE_STAGES;\n}\n\nexport const FACTORY_TRIAGE_TYPES = [\n 'bug',\n 'feature request',\n 'docs',\n 'question/support',\n 'maintenance',\n 'duplicate',\n 'resolved',\n 'invalid',\n 'spam',\n 'out-of-scope',\n 'other',\n] as const;\nexport type FactoryTriageType = (typeof FACTORY_TRIAGE_TYPES)[number];\n\nexport function isFactoryTriageType(value: unknown): value is FactoryTriageType {\n return typeof value === 'string' && FACTORY_TRIAGE_TYPES.some(type => type === value);\n}\n\nexport function isFactoryRuleStage(value: unknown): value is FactoryRuleStage {\n return typeof value === 'string' && FACTORY_RULE_STAGES.some(stage => stage === value);\n}\n\nexport function factoryRuleStage(stages: readonly string[]): FactoryRuleStage | undefined {\n const stage = stages.length === 1 ? stages[0] : undefined;\n return typeof stage === 'string' && stage.length > 0 ? stage : undefined;\n}\n\nexport function isTerminalFactoryRuleStage(stages: readonly string[]): boolean {\n const stage = factoryRuleStage(stages);\n return stage === 'done' || stage === 'canceled';\n}\n\n/** Working lanes hold cards with a seat engaged; Intake, Done and Canceled rest them. */\nexport function isWorkingFactoryRuleStage(stage: FactoryRuleStage): boolean {\n return stage !== 'intake' && !isTerminalFactoryRuleStage([stage]);\n}\n\n// Consulted only for the Intake exit: roles don't own lanes, so a card already\n// in a working or terminal lane stays put when a run starts.\nexport function factoryLaneForRole(role: string): FactoryRuleStage | undefined {\n return isFactoryRole(role) ? FACTORY_ROLE_STAGES[role] : undefined;\n}\n\nexport const FACTORY_RULE_BOARDS = ['work', 'review'] as const;\nexport type FactoryRuleBoard = (typeof FACTORY_RULE_BOARDS)[number] | (string & {});\n\nexport const FACTORY_RULE_SOURCES = [\n 'issue',\n 'pullRequest',\n 'gitlabIssue',\n 'gitlabPullRequest',\n 'linearIssue',\n 'jiraIssue',\n 'incidentioFollowUp',\n 'manual',\n] as const;\nexport type FactoryRuleSource = (typeof FACTORY_RULE_SOURCES)[number];\n\nexport const FACTORY_GITHUB_EVENTS = [\n 'issueOpened',\n 'issueEdited',\n 'issueClosed',\n 'issueCommentCreated',\n 'issueCommentEdited',\n 'issueCommentDeleted',\n 'pullRequestOpened',\n 'pullRequestUpdated',\n 'pullRequestCommentCreated',\n 'pullRequestReviewRequested',\n 'pullRequestReviewSubmitted',\n 'pullRequestMerged',\n 'pullRequestClosed',\n] as const;\nexport type FactoryGithubEventName = (typeof FACTORY_GITHUB_EVENTS)[number];\n\nexport const FACTORY_GITLAB_EVENTS = [\n 'issueOpened',\n 'issueUpdated',\n 'issueClosed',\n 'issueCommented',\n 'mergeRequestOpened',\n 'mergeRequestUpdated',\n 'mergeRequestCommented',\n 'mergeRequestMerged',\n 'mergeRequestClosed',\n] as const;\nexport type FactoryGitLabEventName = (typeof FACTORY_GITLAB_EVENTS)[number];\n\nexport const FACTORY_LINEAR_EVENTS = ['issueObserved', 'issueClosed'] as const;\nexport type FactoryLinearEventName = (typeof FACTORY_LINEAR_EVENTS)[number];\n\nexport const FACTORY_JIRA_EVENTS = ['issueObserved', 'issueClosed'] as const;\nexport type FactoryJiraEventName = (typeof FACTORY_JIRA_EVENTS)[number];\n\nexport const FACTORY_INCIDENTIO_EVENTS = ['followUpObserved', 'followUpClosed'] as const;\nexport type FactoryIncidentioEventName = (typeof FACTORY_INCIDENTIO_EVENTS)[number];\n\nexport type FactoryRuleJsonValue =\n | null\n | boolean\n | number\n | string\n | FactoryRuleJsonValue[]\n | { [key: string]: FactoryRuleJsonValue };\n\nexport interface FactoryRuleItemContext {\n id: string;\n source: WorkItemSource;\n sourceKey: string | null;\n parentWorkItemId: string | null;\n title: string;\n url: string | null;\n stages: readonly string[];\n acceptedAt: Date | null;\n /** Intake-stamped facts about the source — repository id, reporter login, labels. */\n metadata: Record<string, unknown> | null;\n}\n\nexport type FactoryRuleActor =\n | { type: 'human'; id: string }\n | { type: 'agent'; bindingId: string; role: string }\n | { type: 'github'; login: string; trusted: boolean; factoryAuthored: boolean }\n | { type: 'gitlab'; username: string; trusted: boolean; factoryAuthored: boolean }\n | { type: 'system'; id: string };\n\nexport interface FactoryRuleIngressIdentity {\n type: 'human' | 'agent' | 'toolResult' | 'github' | 'gitlab' | 'linear' | 'jira' | 'incidentio' | 'rule';\n id: string;\n}\n\nexport interface FactoryRuleCausalEntry {\n ingressId: string;\n decisionType: FactoryCommitDecision['type'];\n}\n\nexport interface FactoryRuleContextBase {\n tenant: { orgId: string; projectId: string };\n actor: FactoryRuleActor;\n ingress: FactoryRuleIngressIdentity;\n cause: string;\n causalChain: readonly FactoryRuleCausalEntry[];\n configVersion: string;\n}\n\nexport interface FactoryBoundRuleContext extends FactoryRuleContextBase {\n item: FactoryRuleItemContext;\n board: FactoryRuleBoard;\n itemRevision: number;\n}\n\nexport interface FactoryStageRuleContext extends FactoryBoundRuleContext {\n source: FactoryRuleSource;\n stage: FactoryRuleStage;\n fromStage: FactoryRuleStage;\n toStage: FactoryRuleStage;\n}\n\nexport interface FactoryToolResultRuleContext extends FactoryBoundRuleContext {\n toolName: string;\n threadId: string;\n assistantMessageId: string;\n toolCallId: string;\n result: {\n status: 'success' | 'error';\n value: FactoryRuleJsonValue;\n };\n}\n\nexport interface FactoryGithubRuleContext extends FactoryRuleContextBase {\n item?: FactoryRuleItemContext;\n board?: FactoryRuleBoard;\n itemRevision?: number;\n /**\n * Board an issue's labels route it to, when the project has a matching label route and that board\n * is installed. Absent for pull requests and for issues whose labels select nothing.\n */\n intake?: FactoryRuleIntakeTarget;\n /**\n * Set on the one evaluation per pull request delivery that files the pull\n * request's own Review card. Opening a pull request concerns two cards — that\n * Review card and the Work item that authored the pull request — so the rule\n * answers for the two separately: the arrival carries this flag and is\n * committed against the authoring item when resolution found one, which is\n * what links the new card to it, while the authoring item's own evaluation\n * leaves the flag unset.\n */\n pullRequestIntake?: boolean;\n event: FactoryGithubEventName;\n deliveryId: string;\n factory: { createdAt: string };\n repository: { id: number; fullName: string };\n issue?: {\n number: number;\n title: string;\n url: string;\n createdAt?: string;\n updatedAt?: string;\n assignees?: string[];\n labels?: string[];\n state?: 'open' | 'closed';\n /** GitHub close reason: `completed`, `not_planned`, or `duplicate`. */\n stateReason?: string;\n };\n issueChange?: { title: boolean; body: boolean };\n issueComment?: {\n id: number;\n body?: string;\n url?: string;\n author?: string;\n authorType?: string;\n createdAt?: string;\n updatedAt?: string;\n };\n pullRequest?: {\n number: number;\n title: string;\n url: string;\n createdAt?: string;\n state: 'open' | 'closed';\n draft: boolean;\n merged: boolean;\n assignees?: string[];\n requestedReviewers?: string[];\n labels?: string[];\n author?: string;\n factoryAuthored: boolean;\n headBranch: string;\n baseBranch: string;\n };\n /** Present on `pullRequestReviewRequested`: who review was (re-)requested from. */\n reviewRequest?: { reviewer: string; factoryReviewer: boolean };\n /** Present when a PR comment uses Factory's exact review command. */\n reviewCommand?: { command: 'review' | 're-review'; target: string };\n /** Present on `pullRequestReviewSubmitted`: the review that was just posted. */\n review?: { id: number; state: string; url: string };\n}\n\n/**\n * Where an intake source binding says new items from this source should land.\n * Absent when the source is unbound or bound without a board (built-in routing).\n */\nexport interface FactoryRuleIntakeTarget {\n board: string;\n initialPhase: string;\n}\n\nexport interface FactoryGitLabRuleContext extends FactoryRuleContextBase {\n item?: FactoryRuleItemContext;\n board?: FactoryRuleBoard;\n itemRevision?: number;\n intake?: FactoryRuleIntakeTarget;\n event: FactoryGitLabEventName;\n deliveryId: string;\n factory: { createdAt: string };\n repository: { id: number; fullName: string; host: string };\n issue?: {\n number: number;\n sourceKey: string;\n title: string;\n url: string;\n createdAt?: string;\n updatedAt?: string;\n assignees?: string[];\n labels?: string[];\n labelColors?: Record<string, string>;\n state?: 'open' | 'closed';\n author?: string;\n authorTrusted: boolean;\n };\n note?: {\n id: number;\n body?: string;\n url?: string;\n author?: string;\n createdAt?: string;\n updatedAt?: string;\n };\n mergeRequest?: {\n number: number;\n sourceKey: string;\n title: string;\n url: string;\n createdAt?: string;\n state: 'open' | 'closed';\n draft: boolean;\n merged: boolean;\n assignees?: string[];\n reviewers?: string[];\n labels?: string[];\n labelColors?: Record<string, string>;\n author?: string;\n authorTrusted: boolean;\n factoryAuthored: boolean;\n headBranch: string;\n baseBranch: string;\n };\n}\n\nexport interface FactoryLinearRuleContext extends FactoryRuleContextBase {\n item?: FactoryRuleItemContext;\n board?: FactoryRuleBoard;\n itemRevision?: number;\n /** Bound board for the source this issue came from, when one is configured and installed. */\n intake?: FactoryRuleIntakeTarget;\n event: FactoryLinearEventName;\n issue: {\n id: string;\n identifier: string;\n title: string;\n url: string;\n state: string;\n stateType: string;\n priorityLabel: string;\n assignee: string | null;\n creator: string | null;\n team: string | null;\n labels: readonly string[];\n createdAt: string;\n updatedAt: string;\n };\n}\n\nexport interface FactoryJiraRuleContext extends FactoryRuleContextBase {\n item?: FactoryRuleItemContext;\n board?: FactoryRuleBoard;\n itemRevision?: number;\n /** Bound board for the source this issue came from, when one is configured and installed. */\n intake?: FactoryRuleIntakeTarget;\n event: FactoryJiraEventName;\n issue: {\n /** Stable issue reference — the direct integration's Jira id or the Platform-encoded issue reference. */\n id: string;\n identifier: string;\n title: string;\n url: string;\n state: string;\n stateType: string;\n priorityLabel: string;\n assignee: string | null;\n author: string | null;\n project: string | null;\n site: string | null;\n labels: readonly string[];\n createdAt: string;\n updatedAt: string;\n };\n}\n\nexport interface FactoryIncidentioRuleContext extends FactoryRuleContextBase {\n item?: FactoryRuleItemContext;\n board?: FactoryRuleBoard;\n itemRevision?: number;\n /** Bound board for the source this follow-up came from, when one is configured and installed. */\n intake?: FactoryRuleIntakeTarget;\n event: FactoryIncidentioEventName;\n issue: {\n /** Stable item reference — the prefixed incident.io follow-up id the intake feed serves as `id`. */\n id: string;\n identifier: string;\n title: string;\n url: string;\n state: string;\n stateType: string;\n priorityLabel: string;\n assignee: string | null;\n author: string | null;\n /** Reference of the incident this follow-up belongs to, when available. */\n incident: string | null;\n labels: readonly string[];\n createdAt: string;\n updatedAt: string;\n };\n}\n\nexport type FactoryRuleHandler<TContext> = (\n context: Readonly<TContext>,\n) => FactoryRuleDecision | void | Promise<FactoryRuleDecision | void>;\n\nexport interface FactoryBoardRuleLeaf {\n onEnter?: FactoryRuleHandler<FactoryStageRuleContext>;\n onExit?: FactoryRuleHandler<FactoryStageRuleContext>;\n}\n\nexport type FactoryRuleRejectionCode =\n | 'forbidden'\n | 'invalid_transition'\n | 'missing_binding'\n | 'stale'\n | 'timeout'\n | 'rule_error'\n | 'causal_depth_exceeded'\n | 'repeated_transition'\n | 'approval_required';\n\nexport interface FactoryRuleRejectDecision {\n type: 'reject';\n code: FactoryRuleRejectionCode;\n reason: string;\n}\n\ninterface FactoryCommitDecisionBase {\n idempotencyKey: string;\n}\n\nexport interface FactoryTransitionDecision extends FactoryCommitDecisionBase {\n type: 'transition';\n board: FactoryRuleBoard;\n stage: FactoryRuleStage;\n /**\n * Delivered to the item's active session (waking it if idle) after the\n * transition commits. Skipped when the item has no active run binding, so\n * informational messages never fail the transition.\n */\n message?: { text: string; role?: string };\n /**\n * Runs the stage's entry rules even when the item is already in that stage.\n * A transition to the current stage is normally inert, because most callers\n * are correcting a board into a state it already holds. Re-entry is for the\n * opposite case: the stage's work is in flight and has been invalidated, so\n * it has to start over.\n */\n reenter?: boolean;\n}\n\nexport interface FactoryUpsertLinkedWorkItemDecision extends FactoryCommitDecisionBase {\n type: 'upsertLinkedWorkItem';\n board: FactoryRuleBoard;\n source: WorkItemSource;\n sourceKey: string;\n /**\n * Org-wide ownership key for the external record, when one Factory at a time\n * may hold a live card for it (a stable Linear issue id, for instance). The\n * store enforces it with a unique index, so a second project's materialization\n * is refused rather than duplicated.\n */\n claimKey?: string;\n title: string;\n url: string | null;\n stage: FactoryRuleStage;\n /**\n * File the card at `stage` as its first entry and run none of the board's\n * phase rules for it — no arrival, no destination entry. The card is filed\n * (or, if it already exists, moved) and left parked for a person; nothing is\n * started for it. For external records that arrive already past the board's\n * first step: a GitHub issue whose triage is already recorded, for instance.\n *\n * Placement is the whole decision. An existing card it reaches is moved to\n * that stage through the same relocation the label routes use, and its\n * metadata is left alone.\n */\n skipRules?: boolean;\n metadata?: Record<string, FactoryRuleJsonValue>;\n}\n\ninterface FactoryInvokeSkillDecisionBase extends FactoryCommitDecisionBase {\n type: 'invokeSkill';\n role: string;\n arguments?: string;\n precedingMessage?: string;\n cancelInFlight?: boolean;\n}\n\n/**\n * Starting an agent run. Most runs activate a skill, because the skill carries\n * the handoff contract later rules match on. A run whose completion is already\n * signalled some other way — Building finishes by opening a pull request, which\n * arrives as its own event — needs no contract, so it can carry a plain prompt\n * instead of an otherwise empty skill.\n */\nexport type FactoryInvokeSkillDecision = FactoryInvokeSkillDecisionBase &\n (\n | {\n skillName: string;\n prompt?: never;\n /**\n * Same-stage re-entry: the skill is already active in the card's live session,\n * so deliver a compact continuation that references it by name and carries only\n * the fresh arguments, instead of re-pasting the whole skill document. Only valid\n * for named-skill decisions — a plain prompt run has no active skill to resume.\n */\n resume?: boolean;\n }\n | { prompt: string; skillName?: never; resume?: never }\n );\n\nexport interface FactorySendMessageDecision extends FactoryCommitDecisionBase {\n type: 'sendMessage';\n /** Omitted: the card's live session, whichever seat holds it. Required with `prepareBinding`. */\n role?: string;\n message: string;\n priority?: 'medium' | 'high' | 'urgent';\n idleBehavior?: 'persist' | 'wake';\n prepareBinding?: boolean;\n}\n\nexport interface FactoryNotifyDecision extends FactoryCommitDecisionBase {\n type: 'notify';\n title: string;\n body?: string;\n level?: 'info' | 'warning' | 'error';\n}\n\nexport type FactoryCommitDecision =\n | FactoryTransitionDecision\n | FactoryUpsertLinkedWorkItemDecision\n | FactoryInvokeSkillDecision\n | FactorySendMessageDecision\n | FactoryNotifyDecision;\n\nexport type FactoryRuleDecision = FactoryRuleRejectDecision | FactoryCommitDecision;\n\nexport interface FactoryTransitionResultAccepted {\n status: 'accepted';\n transitionId: string;\n itemId: string;\n revision: number;\n stage: FactoryRuleStage;\n decisions: FactoryCommitDecision[];\n}\n\nexport interface FactoryTransitionResultRejected {\n status: 'rejected';\n transitionId: string;\n itemId: string;\n code: FactoryRuleRejectionCode;\n reason: string;\n}\n\nexport type FactoryTransitionResult = FactoryTransitionResultAccepted | FactoryTransitionResultRejected;\n\nexport function factoryRuleSourceForWorkItem(source: WorkItemSource): FactoryRuleSource {\n switch (source) {\n case 'github-issue':\n return 'issue';\n case 'github-pr':\n return 'pullRequest';\n case 'gitlab-issue':\n return 'gitlabIssue';\n case 'gitlab-pr':\n return 'gitlabPullRequest';\n case 'linear-issue':\n return 'linearIssue';\n case 'jira-issue':\n return 'jiraIssue';\n case 'incidentio-follow-up':\n return 'incidentioFollowUp';\n case 'manual':\n return 'manual';\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../src/rules/types.ts"],"sourcesContent":["import type { ExternalWorkItemSource } from '../storage/domains/work-items/base.js';\n\nexport type WorkItemSource =\n | 'github-issue'\n | 'github-pr'\n | 'gitlab-issue'\n | 'gitlab-pr'\n | 'linear-issue'\n | 'jira-issue'\n | 'incidentio-follow-up'\n | 'manual';\n\nexport function externalSourceForWorkItem(\n source: WorkItemSource,\n sourceKey: string,\n url?: string,\n): ExternalWorkItemSource {\n const [integrationId, type] =\n source === 'github-pr'\n ? ['github', 'pull-request']\n : source === 'github-issue'\n ? ['github', 'issue']\n : source === 'gitlab-pr'\n ? ['gitlab', 'pull-request']\n : source === 'gitlab-issue'\n ? ['gitlab', 'issue']\n : source === 'linear-issue'\n ? ['linear', 'issue']\n : source === 'jira-issue'\n ? ['jira', 'issue']\n : source === 'incidentio-follow-up'\n ? ['incidentio', 'issue']\n : ['factory', 'manual'];\n return { integrationId, type, externalId: sourceKey, ...(url ? { url } : {}) };\n}\n\n/** The source label that holds an issue at rest until a maintainer decides; compared lowercased. */\nexport const NEEDS_APPROVAL_LABEL = 'status: needs approval';\nexport const AUTO_TRIAGED_LABEL = 'status: auto-triaged';\n\n// The label only holds a card at rest: once a person accepted it, or it sits in a working\n// lane only a person could have moved it into, the label is stale until the source catches up.\nexport function needsApproval(item: {\n metadata: Record<string, unknown> | null;\n stages?: readonly string[];\n acceptedAt?: Date | string | null;\n}): boolean {\n const labels = item.metadata?.labels;\n if (!Array.isArray(labels)) return false;\n return (\n labels.some(label => typeof label === 'string' && label.toLowerCase() === NEEDS_APPROVAL_LABEL) &&\n !item.acceptedAt &&\n (item.stages ?? ['intake']).every(stage => stage === 'intake' || stage === 'triage')\n );\n}\n\nexport function workItemSource(source: ExternalWorkItemSource | null): WorkItemSource {\n if (!source) return 'manual';\n if (source.integrationId === 'linear') return 'linear-issue';\n if (source.integrationId === 'gitlab') return source.type === 'pull-request' ? 'gitlab-pr' : 'gitlab-issue';\n if (source.integrationId === 'jira') return 'jira-issue';\n if (source.integrationId === 'incidentio') return 'incidentio-follow-up';\n // Only GitHub, GitLab, Linear, Jira, and incident.io have provider-specific\n // rules; anything else (a Slack thread, say) is a plain work item, not a\n // mislabeled GitHub issue.\n if (source.integrationId !== 'github') return 'manual';\n return source.type === 'pull-request' ? 'github-pr' : 'github-issue';\n}\n\n// Authored outside the write-access circle: a missing trust stamp fails closed until\n// the reconcile sweep backfills it, and Factory's own PRs pass through `factoryAuthored`.\nexport function externallyAuthored(item: { source: string; metadata: Record<string, unknown> | null }): boolean {\n if (!['github-pr', 'github-issue', 'gitlab-pr', 'gitlab-issue'].includes(item.source)) return false;\n if (item.metadata?.factoryAuthored === true) return false;\n return item.metadata?.authorTrusted !== true;\n}\n\n// The board mark claims only what GitHub answered: a missing stamp is silence, not an outside contribution.\nexport function knownExternalAuthor(item: { source: string; metadata: Record<string, unknown> | null }): boolean {\n return externallyAuthored(item) && item.metadata?.authorTrusted === false;\n}\n\nexport function externallyAuthoredWorkItem(item: {\n externalSource: ExternalWorkItemSource | null;\n metadata: Record<string, unknown> | null;\n}): boolean {\n return externallyAuthored({ source: workItemSource(item.externalSource), metadata: item.metadata });\n}\n\nexport const FACTORY_RULE_STAGES = ['intake', 'triage', 'planning', 'execute', 'review', 'done', 'canceled'] as const;\nexport type FactoryRuleStage = (typeof FACTORY_RULE_STAGES)[number] | (string & {});\n\n// Each role and the working stage its run holds the card in. Key order is the\n// seat pipeline order — Resume depth derives from it.\nexport const FACTORY_ROLE_STAGES = {\n triage: 'triage',\n plan: 'planning',\n work: 'execute',\n review: 'review',\n} as const satisfies Record<string, FactoryRuleStage>;\nexport type FactoryRole = keyof typeof FACTORY_ROLE_STAGES;\n\nexport function isFactoryRole(value: string): value is FactoryRole {\n return value in FACTORY_ROLE_STAGES;\n}\n\nexport const FACTORY_TRIAGE_TYPES = [\n 'bug',\n 'feature request',\n 'docs',\n 'question/support',\n 'maintenance',\n 'duplicate',\n 'resolved',\n 'invalid',\n 'spam',\n 'out-of-scope',\n 'other',\n] as const;\nexport type FactoryTriageType = (typeof FACTORY_TRIAGE_TYPES)[number];\n\nexport function isFactoryTriageType(value: unknown): value is FactoryTriageType {\n return typeof value === 'string' && FACTORY_TRIAGE_TYPES.some(type => type === value);\n}\n\nexport function isFactoryRuleStage(value: unknown): value is FactoryRuleStage {\n return typeof value === 'string' && FACTORY_RULE_STAGES.some(stage => stage === value);\n}\n\nexport function factoryRuleStage(stages: readonly string[]): FactoryRuleStage | undefined {\n const stage = stages.length === 1 ? stages[0] : undefined;\n return typeof stage === 'string' && stage.length > 0 ? stage : undefined;\n}\n\nexport function isTerminalFactoryRuleStage(stages: readonly string[]): boolean {\n const stage = factoryRuleStage(stages);\n return stage === 'done' || stage === 'canceled';\n}\n\n/** Working lanes hold cards with a seat engaged; Intake, Done and Canceled rest them. */\nexport function isWorkingFactoryRuleStage(stage: FactoryRuleStage): boolean {\n return stage !== 'intake' && !isTerminalFactoryRuleStage([stage]);\n}\n\n// Consulted only for the Intake exit: roles don't own lanes, so a card already\n// in a working or terminal lane stays put when a run starts.\nexport function factoryLaneForRole(role: string): FactoryRuleStage | undefined {\n return isFactoryRole(role) ? FACTORY_ROLE_STAGES[role] : undefined;\n}\n\nexport const FACTORY_RULE_BOARDS = ['work', 'review'] as const;\nexport type FactoryRuleBoard = (typeof FACTORY_RULE_BOARDS)[number] | (string & {});\n\nexport const FACTORY_RULE_SOURCES = [\n 'issue',\n 'pullRequest',\n 'gitlabIssue',\n 'gitlabPullRequest',\n 'linearIssue',\n 'jiraIssue',\n 'incidentioFollowUp',\n 'manual',\n] as const;\nexport type FactoryRuleSource = (typeof FACTORY_RULE_SOURCES)[number];\n\nexport const FACTORY_GITHUB_EVENTS = [\n 'issueOpened',\n 'issueEdited',\n 'issueClosed',\n 'issueCommentCreated',\n 'issueCommentEdited',\n 'issueCommentDeleted',\n 'pullRequestOpened',\n 'pullRequestUpdated',\n 'pullRequestCommentCreated',\n 'pullRequestReviewRequested',\n 'pullRequestReviewSubmitted',\n 'pullRequestMerged',\n 'pullRequestClosed',\n] as const;\nexport type FactoryGithubEventName = (typeof FACTORY_GITHUB_EVENTS)[number];\n\nexport const FACTORY_GITLAB_EVENTS = [\n 'issueOpened',\n 'issueUpdated',\n 'issueClosed',\n 'issueCommented',\n 'mergeRequestOpened',\n 'mergeRequestUpdated',\n 'mergeRequestCommented',\n 'mergeRequestMerged',\n 'mergeRequestClosed',\n] as const;\nexport type FactoryGitLabEventName = (typeof FACTORY_GITLAB_EVENTS)[number];\n\nexport const FACTORY_LINEAR_EVENTS = ['issueObserved', 'issueClosed'] as const;\nexport type FactoryLinearEventName = (typeof FACTORY_LINEAR_EVENTS)[number];\n\nexport const FACTORY_JIRA_EVENTS = ['issueObserved', 'issueClosed'] as const;\nexport type FactoryJiraEventName = (typeof FACTORY_JIRA_EVENTS)[number];\n\nexport const FACTORY_INCIDENTIO_EVENTS = ['followUpObserved', 'followUpClosed'] as const;\nexport type FactoryIncidentioEventName = (typeof FACTORY_INCIDENTIO_EVENTS)[number];\n\nexport type FactoryRuleJsonValue =\n | null\n | boolean\n | number\n | string\n | FactoryRuleJsonValue[]\n | { [key: string]: FactoryRuleJsonValue };\n\nexport interface FactoryRuleItemContext {\n id: string;\n source: WorkItemSource;\n sourceKey: string | null;\n parentWorkItemId: string | null;\n title: string;\n url: string | null;\n stages: readonly string[];\n acceptedAt: Date | null;\n /** Intake-stamped facts about the source — repository id, reporter login, labels. */\n metadata: Record<string, unknown> | null;\n}\n\nexport type FactoryRuleActor =\n | { type: 'human'; id: string }\n | { type: 'agent'; bindingId: string; role: string }\n | { type: 'github'; login: string; trusted: boolean; factoryAuthored: boolean }\n | { type: 'gitlab'; username: string; trusted: boolean; factoryAuthored: boolean }\n | { type: 'system'; id: string };\n\nexport interface FactoryRuleIngressIdentity {\n type: 'human' | 'agent' | 'toolResult' | 'github' | 'gitlab' | 'linear' | 'jira' | 'incidentio' | 'rule';\n id: string;\n}\n\nexport interface FactoryRuleCausalEntry {\n ingressId: string;\n decisionType: FactoryCommitDecision['type'];\n}\n\nexport interface FactoryRuleContextBase {\n tenant: { orgId: string; projectId: string };\n actor: FactoryRuleActor;\n ingress: FactoryRuleIngressIdentity;\n cause: string;\n causalChain: readonly FactoryRuleCausalEntry[];\n configVersion: string;\n}\n\nexport interface FactoryBoundRuleContext extends FactoryRuleContextBase {\n item: FactoryRuleItemContext;\n board: FactoryRuleBoard;\n itemRevision: number;\n}\n\nexport interface FactoryStageRuleContext extends FactoryBoundRuleContext {\n source: FactoryRuleSource;\n stage: FactoryRuleStage;\n fromStage: FactoryRuleStage;\n toStage: FactoryRuleStage;\n}\n\nexport interface FactoryToolResultRuleContext extends FactoryBoundRuleContext {\n toolName: string;\n threadId: string;\n assistantMessageId: string;\n toolCallId: string;\n result: {\n status: 'success' | 'error';\n value: FactoryRuleJsonValue;\n };\n}\n\nexport interface FactoryGithubRuleContext extends FactoryRuleContextBase {\n item?: FactoryRuleItemContext;\n board?: FactoryRuleBoard;\n itemRevision?: number;\n /**\n * Board an issue's labels route it to, when the project has a matching label route and that board\n * is installed. Absent for pull requests and for issues whose labels select nothing.\n */\n intake?: FactoryRuleIntakeTarget;\n /**\n * Set on the one evaluation per pull request delivery that files the pull\n * request's own Review card. Opening a pull request concerns two cards — that\n * Review card and the Work item that authored the pull request — so the rule\n * answers for the two separately: the arrival carries this flag and is\n * committed against the authoring item when resolution found one, which is\n * what links the new card to it, while the authoring item's own evaluation\n * leaves the flag unset.\n */\n pullRequestIntake?: boolean;\n event: FactoryGithubEventName;\n deliveryId: string;\n factory: { createdAt: string };\n repository: { id: number; fullName: string };\n issue?: {\n number: number;\n title: string;\n url: string;\n createdAt?: string;\n updatedAt?: string;\n assignees?: string[];\n labels?: string[];\n state?: 'open' | 'closed';\n /** GitHub close reason: `completed`, `not_planned`, or `duplicate`. */\n stateReason?: string;\n };\n issueChange?: { title: boolean; body: boolean };\n issueComment?: {\n id: number;\n body?: string;\n url?: string;\n author?: string;\n authorType?: string;\n createdAt?: string;\n updatedAt?: string;\n };\n pullRequest?: {\n number: number;\n title: string;\n url: string;\n createdAt?: string;\n state: 'open' | 'closed';\n draft: boolean;\n merged: boolean;\n assignees?: string[];\n requestedReviewers?: string[];\n labels?: string[];\n author?: string;\n factoryAuthored: boolean;\n headBranch: string;\n baseBranch: string;\n };\n /** Present on `pullRequestReviewRequested`: who review was (re-)requested from. */\n reviewRequest?: { reviewer: string; factoryReviewer: boolean };\n /** Present when a PR comment uses Factory's exact review command. */\n reviewCommand?: { command: 'review' | 're-review'; target: string };\n /** Present on `pullRequestReviewSubmitted`: the review that was just posted. */\n review?: { id: number; state: string; url: string };\n}\n\n/**\n * Where an intake source binding says new items from this source should land.\n * Absent when the source is unbound or bound without a board (built-in routing).\n */\nexport interface FactoryRuleIntakeTarget {\n board: string;\n initialPhase: string;\n}\n\nexport interface FactoryGitLabRuleContext extends FactoryRuleContextBase {\n item?: FactoryRuleItemContext;\n board?: FactoryRuleBoard;\n itemRevision?: number;\n intake?: FactoryRuleIntakeTarget;\n event: FactoryGitLabEventName;\n deliveryId: string;\n factory: { createdAt: string };\n repository: { id: number; fullName: string; host: string };\n issue?: {\n number: number;\n sourceKey: string;\n title: string;\n url: string;\n createdAt?: string;\n updatedAt?: string;\n assignees?: string[];\n labels?: string[];\n labelColors?: Record<string, string>;\n state?: 'open' | 'closed';\n author?: string;\n authorTrusted: boolean;\n };\n note?: {\n id: number;\n body?: string;\n url?: string;\n author?: string;\n createdAt?: string;\n updatedAt?: string;\n };\n mergeRequest?: {\n number: number;\n sourceKey: string;\n title: string;\n url: string;\n createdAt?: string;\n state: 'open' | 'closed';\n draft: boolean;\n merged: boolean;\n assignees?: string[];\n reviewers?: string[];\n labels?: string[];\n labelColors?: Record<string, string>;\n author?: string;\n authorTrusted: boolean;\n factoryAuthored: boolean;\n headBranch: string;\n baseBranch: string;\n };\n}\n\nexport interface FactoryLinearRuleContext extends FactoryRuleContextBase {\n item?: FactoryRuleItemContext;\n board?: FactoryRuleBoard;\n itemRevision?: number;\n /** Bound board for the source this issue came from, when one is configured and installed. */\n intake?: FactoryRuleIntakeTarget;\n event: FactoryLinearEventName;\n issue: {\n id: string;\n identifier: string;\n title: string;\n url: string;\n state: string;\n stateType: string;\n priorityLabel: string;\n assignee: string | null;\n creator: string | null;\n team: string | null;\n labels: readonly string[];\n createdAt: string;\n updatedAt: string;\n sourceId?: string | null;\n projectId?: string | null;\n };\n}\n\nexport interface FactoryJiraRuleContext extends FactoryRuleContextBase {\n item?: FactoryRuleItemContext;\n board?: FactoryRuleBoard;\n itemRevision?: number;\n /** Bound board for the source this issue came from, when one is configured and installed. */\n intake?: FactoryRuleIntakeTarget;\n event: FactoryJiraEventName;\n issue: {\n /** Stable issue reference — the direct integration's Jira id or the Platform-encoded issue reference. */\n id: string;\n identifier: string;\n title: string;\n url: string;\n state: string;\n stateType: string;\n priorityLabel: string;\n assignee: string | null;\n author: string | null;\n project: string | null;\n site: string | null;\n labels: readonly string[];\n createdAt: string;\n updatedAt: string;\n };\n}\n\nexport interface FactoryIncidentioRuleContext extends FactoryRuleContextBase {\n item?: FactoryRuleItemContext;\n board?: FactoryRuleBoard;\n itemRevision?: number;\n /** Bound board for the source this follow-up came from, when one is configured and installed. */\n intake?: FactoryRuleIntakeTarget;\n event: FactoryIncidentioEventName;\n issue: {\n /** Stable item reference — the prefixed incident.io follow-up id the intake feed serves as `id`. */\n id: string;\n identifier: string;\n title: string;\n url: string;\n state: string;\n stateType: string;\n priorityLabel: string;\n assignee: string | null;\n author: string | null;\n /** Reference of the incident this follow-up belongs to, when available. */\n incident: string | null;\n labels: readonly string[];\n createdAt: string;\n updatedAt: string;\n };\n}\n\nexport type FactoryRuleHandler<TContext> = (\n context: Readonly<TContext>,\n) => FactoryRuleDecision | void | Promise<FactoryRuleDecision | void>;\n\nexport interface FactoryBoardRuleLeaf {\n onEnter?: FactoryRuleHandler<FactoryStageRuleContext>;\n onExit?: FactoryRuleHandler<FactoryStageRuleContext>;\n}\n\nexport type FactoryRuleRejectionCode =\n | 'forbidden'\n | 'invalid_transition'\n | 'missing_binding'\n | 'stale'\n | 'timeout'\n | 'rule_error'\n | 'causal_depth_exceeded'\n | 'repeated_transition'\n | 'approval_required';\n\nexport interface FactoryRuleRejectDecision {\n type: 'reject';\n code: FactoryRuleRejectionCode;\n reason: string;\n}\n\ninterface FactoryCommitDecisionBase {\n idempotencyKey: string;\n}\n\nexport interface FactoryTransitionDecision extends FactoryCommitDecisionBase {\n type: 'transition';\n board: FactoryRuleBoard;\n stage: FactoryRuleStage;\n /**\n * Delivered to the item's active session (waking it if idle) after the\n * transition commits. Skipped when the item has no active run binding, so\n * informational messages never fail the transition.\n */\n message?: { text: string; role?: string };\n /**\n * Runs the stage's entry rules even when the item is already in that stage.\n * A transition to the current stage is normally inert, because most callers\n * are correcting a board into a state it already holds. Re-entry is for the\n * opposite case: the stage's work is in flight and has been invalidated, so\n * it has to start over.\n */\n reenter?: boolean;\n}\n\nexport interface FactoryUpsertLinkedWorkItemDecision extends FactoryCommitDecisionBase {\n type: 'upsertLinkedWorkItem';\n board: FactoryRuleBoard;\n source: WorkItemSource;\n sourceKey: string;\n /**\n * Org-wide ownership key for the external record, when one Factory at a time\n * may hold a live card for it (a stable Linear issue id, for instance). The\n * store enforces it with a unique index, so a second project's materialization\n * is refused rather than duplicated.\n */\n claimKey?: string;\n title: string;\n url: string | null;\n stage: FactoryRuleStage;\n /**\n * File the card at `stage` as its first entry and run none of the board's\n * phase rules for it — no arrival, no destination entry. The card is filed\n * (or, if it already exists, moved) and left parked for a person; nothing is\n * started for it. For external records that arrive already past the board's\n * first step: a GitHub issue whose triage is already recorded, for instance.\n *\n * Placement is the whole decision. An existing card it reaches is moved to\n * that stage through the same relocation the label routes use, and its\n * metadata is left alone.\n */\n skipRules?: boolean;\n metadata?: Record<string, FactoryRuleJsonValue>;\n}\n\ninterface FactoryInvokeSkillDecisionBase extends FactoryCommitDecisionBase {\n type: 'invokeSkill';\n role: string;\n arguments?: string;\n precedingMessage?: string;\n cancelInFlight?: boolean;\n}\n\n/**\n * Starting an agent run. Most runs activate a skill, because the skill carries\n * the handoff contract later rules match on. A run whose completion is already\n * signalled some other way — Building finishes by opening a pull request, which\n * arrives as its own event — needs no contract, so it can carry a plain prompt\n * instead of an otherwise empty skill.\n */\nexport type FactoryInvokeSkillDecision = FactoryInvokeSkillDecisionBase &\n (\n | {\n skillName: string;\n prompt?: never;\n /**\n * Same-stage re-entry: the skill is already active in the card's live session,\n * so deliver a compact continuation that references it by name and carries only\n * the fresh arguments, instead of re-pasting the whole skill document. Only valid\n * for named-skill decisions — a plain prompt run has no active skill to resume.\n */\n resume?: boolean;\n }\n | { prompt: string; skillName?: never; resume?: never }\n );\n\nexport interface FactorySendMessageDecision extends FactoryCommitDecisionBase {\n type: 'sendMessage';\n /** Omitted: the card's live session, whichever seat holds it. Required with `prepareBinding`. */\n role?: string;\n message: string;\n priority?: 'medium' | 'high' | 'urgent';\n idleBehavior?: 'persist' | 'wake';\n prepareBinding?: boolean;\n}\n\nexport interface FactoryNotifyDecision extends FactoryCommitDecisionBase {\n type: 'notify';\n title: string;\n body?: string;\n level?: 'info' | 'warning' | 'error';\n}\n\nexport type FactoryCommitDecision =\n | FactoryTransitionDecision\n | FactoryUpsertLinkedWorkItemDecision\n | FactoryInvokeSkillDecision\n | FactorySendMessageDecision\n | FactoryNotifyDecision;\n\nexport type FactoryRuleDecision = FactoryRuleRejectDecision | FactoryCommitDecision;\n\nexport interface FactoryTransitionResultAccepted {\n status: 'accepted';\n transitionId: string;\n itemId: string;\n revision: number;\n stage: FactoryRuleStage;\n decisions: FactoryCommitDecision[];\n}\n\nexport interface FactoryTransitionResultRejected {\n status: 'rejected';\n transitionId: string;\n itemId: string;\n code: FactoryRuleRejectionCode;\n reason: string;\n}\n\nexport type FactoryTransitionResult = FactoryTransitionResultAccepted | FactoryTransitionResultRejected;\n\nexport function factoryRuleSourceForWorkItem(source: WorkItemSource): FactoryRuleSource {\n switch (source) {\n case 'github-issue':\n return 'issue';\n case 'github-pr':\n return 'pullRequest';\n case 'gitlab-issue':\n return 'gitlabIssue';\n case 'gitlab-pr':\n return 'gitlabPullRequest';\n case 'linear-issue':\n return 'linearIssue';\n case 'jira-issue':\n return 'jiraIssue';\n case 'incidentio-follow-up':\n return 'incidentioFollowUp';\n case 'manual':\n return 'manual';\n }\n}\n"],"mappings":"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"}
|
|
@@ -53,8 +53,8 @@ export interface EnsureFactorySourceSessionArgs {
|
|
|
53
53
|
orgId: string;
|
|
54
54
|
factoryProjectId: string;
|
|
55
55
|
branch: string;
|
|
56
|
-
/** Pick
|
|
57
|
-
repositorySlug
|
|
56
|
+
/** Pick the linked repository that the work item targets. */
|
|
57
|
+
repositorySlug: string;
|
|
58
58
|
/**
|
|
59
59
|
* Attribute the run to this user instead of the repo connector. Set when the
|
|
60
60
|
* run has an interactive user — e.g. the person who approved a proposed run.
|
|
@@ -102,8 +102,12 @@ export declare function resolveFactorySourceRepository(args: {
|
|
|
102
102
|
sourceControl: SourceControlStorageHandle;
|
|
103
103
|
orgId: string;
|
|
104
104
|
factoryProjectId: string;
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
repositorySlug: string;
|
|
106
|
+
} | {
|
|
107
|
+
sourceControl: SourceControlStorageHandle;
|
|
108
|
+
orgId: string;
|
|
109
|
+
factoryProjectId: string;
|
|
110
|
+
firstLinkedRepository: true;
|
|
107
111
|
}): Promise<FactorySourceRepositoryResult>;
|
|
108
112
|
/**
|
|
109
113
|
* Walk a Factory user-session id back to the project it belongs to.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory-session.d.ts","sourceRoot":"","sources":["../../src/session/factory-session.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAGrE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AACxF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAChC,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAA6B,KAAK,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAGvG,KAAK,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AAE7F,qBAAa,iCAAkC,SAAQ,KAAK;CAAG;AAE/D;;;GAGG;AACH,wBAAsB,4BAA4B,CAChD,QAAQ,EAAE,sBAAsB,GAAG,SAAS,EAC5C,gBAAgB,EAAE,MAAM,GAAG,SAAS,GACnC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAQ7B;AAED,MAAM,WAAW,0BAA0B;IACzC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;IACxE,2BAA2B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,0BAA0B,GAAG,IAAI,CAAC,CAAC;IAC3F,MAAM,CAAC,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,gBAAgB,CAAC,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,uBAAuB,CAAC,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrE;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAC9C,cAAc,EAAE,SAAS,0BAA0B,EAAE,GACpD,0BAA0B,CA2B5B;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,CAAC,IAAI,EAAE;IACtD,cAAc,EAAE,SAAS,0BAA0B,EAAE,CAAC;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC,CAwClD;AAED,MAAM,WAAW,8BAA8B;IAC7C;;;;;OAKG;IACH,aAAa,EAAE,0BAA0B,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,
|
|
1
|
+
{"version":3,"file":"factory-session.d.ts","sourceRoot":"","sources":["../../src/session/factory-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -92,7 +92,9 @@ var FactorySourceSessionResolutionError = class extends Error {
|
|
|
92
92
|
* handle's own `integrationId` — nothing here is provider-specific.
|
|
93
93
|
*/
|
|
94
94
|
async function resolveFactorySourceRepository(args) {
|
|
95
|
-
const { sourceControl, orgId, factoryProjectId
|
|
95
|
+
const { sourceControl, orgId, factoryProjectId } = args;
|
|
96
|
+
const repositorySlug = "repositorySlug" in args ? args.repositorySlug : void 0;
|
|
97
|
+
const firstLinkedRepository = "firstLinkedRepository" in args;
|
|
96
98
|
const candidates = (await sourceControl.connections.list({
|
|
97
99
|
orgId,
|
|
98
100
|
factoryProjectId
|
|
@@ -114,7 +116,7 @@ async function resolveFactorySourceRepository(args) {
|
|
|
114
116
|
orgId,
|
|
115
117
|
id: projectRepository.repositoryId
|
|
116
118
|
})
|
|
117
|
-
})))).find((candidate) => candidate.repository && (
|
|
119
|
+
})))).find((candidate) => candidate.repository && (firstLinkedRepository || candidate.repository.slug === repositorySlug));
|
|
118
120
|
} catch (error) {
|
|
119
121
|
if (!(error instanceof SourceControlConnectionNotFoundError)) throw error;
|
|
120
122
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory-session.js","names":[],"sources":["../../src/session/factory-session.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport { resolveProviderOMDefault } from '@mastra/code-sdk/onboarding/packs';\nimport type { MastraCodeState } from '@mastra/code-sdk/schema';\nimport type { AgentController } from '@mastra/core/agent-controller';\n\nimport { factoryMemorySettingsUserId } from '../storage/domains/memory-settings/base.js';\nimport type { MemorySettingsStorage } from '../storage/domains/memory-settings/base.js';\nimport type { FactoryProjectsStorage } from '../storage/domains/projects/base.js';\nimport {\n SourceControlConnectionNotFoundError,\n type SourceControlSession,\n type SourceControlStorageHandle,\n} from '../storage/domains/source-control/base.js';\nimport { applyStoredMemorySettings, type OMConfigurableSession } from './memory-settings-hydration.js';\nimport { seedSessionOrg } from './org-seed.js';\n\ntype FactorySession = Awaited<ReturnType<AgentController<MastraCodeState>['createSession']>>;\n\nexport class FactorySourceControlConflictError extends Error {}\n\n/**\n * Read the factory project's default model. Best-effort: a missing project or an\n * uninitialized storage domain means \"no default\", never a failed run.\n */\nexport async function resolveFactoryDefaultModelId(\n projects: FactoryProjectsStorage | undefined,\n factoryProjectId: string | undefined,\n): Promise<string | undefined> {\n if (!projects || !factoryProjectId) return undefined;\n try {\n const project = await projects.getById({ id: factoryProjectId });\n return project?.defaultModelId ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nexport interface SourceControlSessionLookup {\n getBySessionId(sessionId: string): Promise<SourceControlSession | null>;\n getSourceControlBySessionId(sessionId: string): Promise<SourceControlStorageHandle | null>;\n rename(args: { sessionId: string; title: string }): Promise<void>;\n markFirstMessage(args: { sessionId: string }): Promise<void>;\n markFirstMeaningfulExec(args: { sessionId: string }): Promise<void>;\n}\n\n/**\n * Read or update a session across every registered source-control partition.\n * Session ids are globally generated, so more than one match is invalid and\n * fails closed instead of mutating an arbitrary provider.\n */\nexport function createSourceControlSessionLookup(\n sourceControls: readonly SourceControlStorageHandle[],\n): SourceControlSessionLookup {\n const resolve = async (\n sessionId: string,\n ): Promise<{ sourceControl: SourceControlStorageHandle; session: SourceControlSession } | null> => {\n const matches = (\n await Promise.all(\n sourceControls.map(async sourceControl => ({\n sourceControl,\n session: await sourceControl.sessions.getBySessionId(sessionId),\n })),\n )\n ).filter(\n (match): match is { sourceControl: SourceControlStorageHandle; session: SourceControlSession } =>\n match.session !== null,\n );\n if (matches.length > 1) throw new Error('Factory session exists in multiple source-control providers.');\n return matches[0] ?? null;\n };\n\n return {\n getBySessionId: async sessionId => (await resolve(sessionId))?.session ?? null,\n getSourceControlBySessionId: async sessionId => (await resolve(sessionId))?.sourceControl ?? null,\n rename: async args => (await resolve(args.sessionId))?.sourceControl.sessions.rename(args),\n markFirstMessage: async args => (await resolve(args.sessionId))?.sourceControl.sessions.markFirstMessage(args),\n markFirstMeaningfulExec: async args =>\n (await resolve(args.sessionId))?.sourceControl.sessions.markFirstMeaningfulExec(args),\n };\n}\n\n/**\n * Resolve the source-control provider from durable Factory repository links,\n * never from the issue tracker that happened to create the work item.\n */\nexport async function resolveFactorySourceControl(args: {\n sourceControls: readonly SourceControlStorageHandle[];\n orgId: string;\n factoryProjectId: string;\n sessionId?: string;\n}): Promise<SourceControlStorageHandle | undefined> {\n if (args.sessionId) {\n const sessionMatches = (\n await Promise.all(\n args.sourceControls.map(async sourceControl => ({\n sourceControl,\n session: await sourceControl.sessions.getBySessionId(args.sessionId!),\n })),\n )\n ).filter(match => match.session !== null);\n if (sessionMatches.length > 1) throw new Error('Factory session exists in multiple source-control providers.');\n if (sessionMatches[0]) return sessionMatches[0].sourceControl;\n }\n\n const linked = [];\n for (const sourceControl of args.sourceControls) {\n const connections = await sourceControl.connections.list({\n orgId: args.orgId,\n factoryProjectId: args.factoryProjectId,\n });\n let hasLinkedRepository = false;\n for (const connection of connections) {\n try {\n if (\n (await sourceControl.projectRepositories.list({ orgId: args.orgId, connectionId: connection.id })).length > 0\n ) {\n hasLinkedRepository = true;\n break;\n }\n } catch (error) {\n if (!(error instanceof SourceControlConnectionNotFoundError)) throw error;\n }\n }\n if (hasLinkedRepository) linked.push(sourceControl);\n }\n if (linked.length > 1)\n throw new FactorySourceControlConflictError(\n 'Factory project has repositories linked through multiple source-control providers.',\n );\n return linked[0];\n}\n\nexport interface EnsureFactorySourceSessionArgs {\n /**\n * Storage handle of the integration that owns source control. Nothing here is\n * provider-specific: the connection is matched by the handle's own\n * `integrationId`, so GitHub, Slack-on-behalf-of-GitHub, or any future owner\n * all resolve through the same traversal.\n */\n sourceControl: SourceControlStorageHandle;\n orgId: string;\n factoryProjectId: string;\n branch: string;\n /** Pick a specific linked repository by slug. Defaults to the first linked repository. */\n repositorySlug?: string;\n /**\n * Attribute the run to this user instead of the repo connector. Set when the\n * run has an interactive user — e.g. the person who approved a proposed run.\n */\n attributeToUserId?: string;\n}\n\nexport interface EnsuredFactorySourceSession {\n sessionId: string;\n userId: string;\n projectRepositoryId: string;\n branch: string;\n baseBranch: string;\n}\n\nexport class FactorySourceSessionResolutionError extends Error {\n constructor(readonly reason: 'connection' | 'repository') {\n super(\n reason === 'connection'\n ? 'Factory source-control connection not found.'\n : 'Factory source-control repository not found.',\n );\n this.name = 'FactorySourceSessionResolutionError';\n }\n}\n\nexport interface ResolvedFactorySourceRepository {\n projectRepositoryId: string;\n /** The repository's pinned branch, else its default branch. */\n baseBranch: string;\n /** Who connected the repository. The attribution for runs with no interactive user. */\n connectedByUserId: string;\n}\n\n/**\n * Outcome of {@link resolveFactorySourceRepository}. A miss carries which step\n * failed: callers differ on whether that is an error (an autonomous run cannot\n * proceed) or a routine fallback (a chat integration drops to a chat-only\n * session), and the two steps fail for different reasons worth reporting apart.\n */\nexport type FactorySourceRepositoryResult =\n | ({ found: true } & ResolvedFactorySourceRepository)\n | { found: false; reason: 'connection' | 'repository' };\n\n/**\n * Resolve which repository a factory project's source-control runs act on: the\n * owner's connection on the project, then one of its linked repositories.\n *\n * The owner is whichever integration owns source control, matched by the\n * handle's own `integrationId` — nothing here is provider-specific.\n */\nexport async function resolveFactorySourceRepository(args: {\n sourceControl: SourceControlStorageHandle;\n orgId: string;\n factoryProjectId: string;\n /** Pick a specific linked repository by slug. Defaults to the first linked repository. */\n repositorySlug?: string;\n}): Promise<FactorySourceRepositoryResult> {\n const { sourceControl, orgId, factoryProjectId, repositorySlug } = args;\n\n const connections = await sourceControl.connections.list({ orgId, factoryProjectId });\n const candidates = connections.filter(candidate => candidate.integrationId === sourceControl.integrationId);\n if (candidates.length === 0) return { found: false, reason: 'connection' };\n\n // A project can carry stale connections: a provider-app reinstall leaves the\n // old connection pointing at an installation that no longer exists, and that\n // row can sit ahead of the healthy one. Try every candidate and skip the ones\n // that no longer resolve rather than failing on the first.\n for (const connection of candidates) {\n let resolved;\n try {\n const projectRepositories = await sourceControl.projectRepositories.list({ orgId, connectionId: connection.id });\n const resolvedRepositories = await Promise.all(\n projectRepositories.map(async projectRepository => ({\n projectRepository,\n repository: await sourceControl.repositories.get({ orgId, id: projectRepository.repositoryId }),\n })),\n );\n resolved = resolvedRepositories.find(\n candidate => candidate.repository && (!repositorySlug || candidate.repository.slug === repositorySlug),\n );\n } catch (error) {\n // A deleted installation invalidates a stale connection; storage failures must propagate.\n if (!(error instanceof SourceControlConnectionNotFoundError)) throw error;\n continue;\n }\n if (!resolved?.repository) continue;\n\n return {\n found: true,\n projectRepositoryId: resolved.projectRepository.id,\n baseBranch: resolved.projectRepository.branch ?? resolved.repository.defaultBranch,\n connectedByUserId: connection.createdByUserId,\n };\n }\n\n return { found: false, reason: 'repository' };\n}\n\n/**\n * Walk a Factory user-session id back to the project it belongs to.\n *\n * Repo-backed channel threads are keyed by their Factory session id, which is\n * the only handle a session-start hook gets. This turns that id back into the\n * project whose configuration the session should adopt. Durable by\n * construction — it reads the same rows the session was created from, so it\n * survives restarts without any in-memory mapping.\n */\nexport async function resolveFactoryProjectForSession(args: {\n sourceControl: SourceControlStorageHandle;\n sessionId: string;\n}): Promise<{ factoryProjectId: string; orgId: string; userId: string } | null> {\n const { sourceControl, sessionId } = args;\n\n const session = await sourceControl.sessions.getBySessionId(sessionId);\n if (!session) return null;\n const projectRepository = await sourceControl.projectRepositories.get({\n orgId: session.orgId,\n id: session.projectRepositoryId,\n });\n if (!projectRepository) return null;\n const connection = await sourceControl.connections.get({ orgId: session.orgId, id: projectRepository.connectionId });\n if (!connection) return null;\n\n return { factoryProjectId: connection.factoryProjectId, orgId: session.orgId, userId: session.userId };\n}\n\n/**\n * Create the source-control session a repo-backed factory run needs.\n *\n * `FactoryStartCoordinator.prepare` requires this record to already exist —\n * `resolveSourceSession` throws `Factory session not found` otherwise — so every\n * autonomous entry point has to produce one before it can start a run. This is\n * that step, in one place: the owner's connection on the factory project, one of\n * its linked repositories, and a session on the requested branch with the\n * repository's pinned or default branch as the base.\n *\n * The run is attributed to `attributeToUserId` when the caller has an\n * interactive user (e.g. the approver of a proposed run), and otherwise falls\n * back to whoever connected the repository (`connection.createdByUserId`),\n * because a genuinely autonomous run has no interactive user of its own.\n */\nexport async function ensureFactorySourceSession(\n args: EnsureFactorySourceSessionArgs,\n): Promise<EnsuredFactorySourceSession> {\n const { sourceControl, orgId, factoryProjectId, branch, repositorySlug } = args;\n\n const resolved = await resolveFactorySourceRepository({ sourceControl, orgId, factoryProjectId, repositorySlug });\n if (!resolved.found) throw new FactorySourceSessionResolutionError(resolved.reason);\n\n const userId = args.attributeToUserId ?? resolved.connectedByUserId;\n const session = await sourceControl.sessions.create({\n sessionId: randomUUID(),\n projectRepositoryId: resolved.projectRepositoryId,\n orgId,\n userId,\n branch,\n baseBranch: resolved.baseBranch,\n visibility: 'org',\n });\n return {\n sessionId: session.sessionId,\n userId,\n projectRepositoryId: resolved.projectRepositoryId,\n branch: session.branch,\n baseBranch: resolved.baseBranch,\n };\n}\n\nexport interface HydrateFactorySessionArgs {\n orgId: string;\n /**\n * The factory project whose shared memory settings apply. Factory sessions\n * never read an individual user's personal memory settings — the project's\n * own row (or the built-in defaults) is what they run with.\n */\n factoryProjectId?: string;\n /** The factory project's default model. Without it the session keeps the SDK's built-in mode default. */\n defaultModelId?: string;\n /**\n * When provided, the factory project's stored memory-settings row is\n * applied. When omitted (or no row exists) the session is reset to the\n * built-in memory defaults.\n */\n memorySettings?: MemorySettingsStorage;\n}\n\n/**\n * Apply a factory project's configuration to a freshly created session:\n * observational-memory settings, then the project's default model.\n *\n * Both steps are best-effort. A retired model id or an unreachable settings row\n * must not sink a run that is otherwise ready — the session simply keeps the\n * default it was created with, and the reason is logged.\n */\nexport async function hydrateFactorySession(session: FactorySession, args: HydrateFactorySessionArgs): Promise<void> {\n // The org rung knowledge curation scopes on. Seeded first so it lands even if\n // a later best-effort step fails; an empty org marks the session unresolved.\n await seedSessionOrg(session, args.orgId);\n try {\n const record =\n args.memorySettings && args.factoryProjectId\n ? await args.memorySettings.get({\n orgId: args.orgId,\n userId: factoryMemorySettingsUserId(args.factoryProjectId),\n })\n : null;\n // Without a stored row, fall back to the low-cost OM model of the factory\n // default model's provider — a factory connected only to Anthropic should\n // not observe with the (uncredentialed) built-in Google default.\n const provider = args.defaultModelId?.split('/')[0];\n const fallbackOmModelId = provider ? resolveProviderOMDefault(provider, args.defaultModelId).modelId : undefined;\n await applyStoredMemorySettings(session, record, fallbackOmModelId);\n } catch (error) {\n console.warn('[Factory Start] Failed to apply observational-memory settings', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n if (args.defaultModelId) {\n try {\n await session.model.switch({ modelId: args.defaultModelId });\n } catch (error) {\n console.warn('[Factory Start] Failed to apply factory default model', {\n modelId: args.defaultModelId,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n}\n\nexport interface RefreshFactorySessionMemorySettingsArgs {\n orgId: string;\n factoryProjectId: string;\n projects: Pick<FactoryProjectsStorage, 'get'>;\n memorySettings: Pick<MemorySettingsStorage, 'get'>;\n}\n\n/**\n * Re-apply a factory project's stored observational-memory settings to an\n * already-running session that automation is about to reuse. Session creation\n * hydrates these settings once (`hydrateFactorySession`), but a reused binding\n * keeps whatever observer/reflector models it was created with — so a project\n * whose OM models changed since would keep observing with the stale (and\n * possibly since-rejected) models. This reads the project's current row with the\n * same provider-aware fallback as initial hydration and applies it, mirroring\n * the `GET /web/config/om` refresh. Best-effort: a settings lookup failure must\n * never sink an otherwise-ready run, so it is logged and swallowed.\n */\nexport async function refreshFactorySessionMemorySettings(\n session: OMConfigurableSession,\n args: RefreshFactorySessionMemorySettingsArgs,\n): Promise<void> {\n try {\n const record = await args.memorySettings.get({\n orgId: args.orgId,\n userId: factoryMemorySettingsUserId(args.factoryProjectId),\n });\n const project = await args.projects.get({ orgId: args.orgId, id: args.factoryProjectId });\n const provider = project?.defaultModelId?.split('/')[0];\n const fallbackOmModelId = provider\n ? resolveProviderOMDefault(provider, project?.defaultModelId ?? undefined).modelId\n : undefined;\n await applyStoredMemorySettings(session, record, fallbackOmModelId);\n } catch (error) {\n console.warn('[Factory dispatch] Failed to reapply observational-memory settings on session reuse', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n}\n"],"mappings":";;;;;;;AAmBA,IAAa,oCAAb,cAAuD,MAAM,CAAC;;;;;AAM9D,eAAsB,6BACpB,UACA,kBAC6B;CAC7B,IAAI,CAAC,YAAY,CAAC,kBAAkB,OAAO,KAAA;CAC3C,IAAI;EAEF,QAAO,MADe,SAAS,QAAQ,EAAE,IAAI,iBAAiB,CAAC,EAAA,EAC/C,kBAAkB,KAAA;CACpC,QAAQ;EACN;CACF;AACF;;;;;;AAeA,SAAgB,iCACd,gBAC4B;CAC5B,MAAM,UAAU,OACd,cACiG;EACjG,MAAM,WACJ,MAAM,QAAQ,IACZ,eAAe,IAAI,OAAM,mBAAkB;GACzC;GACA,SAAS,MAAM,cAAc,SAAS,eAAe,SAAS;EAChE,EAAE,CACJ,EAAA,CACA,QACC,UACC,MAAM,YAAY,IACtB;EACA,IAAI,QAAQ,SAAS,GAAG,MAAM,IAAI,MAAM,8DAA8D;EACtG,OAAO,QAAQ,MAAM;CACvB;CAEA,OAAO;EACL,gBAAgB,OAAM,eAAc,MAAM,QAAQ,SAAS,EAAA,EAAI,WAAW;EAC1E,6BAA6B,OAAM,eAAc,MAAM,QAAQ,SAAS,EAAA,EAAI,iBAAiB;EAC7F,QAAQ,OAAM,UAAS,MAAM,QAAQ,KAAK,SAAS,EAAA,EAAI,cAAc,SAAS,OAAO,IAAI;EACzF,kBAAkB,OAAM,UAAS,MAAM,QAAQ,KAAK,SAAS,EAAA,EAAI,cAAc,SAAS,iBAAiB,IAAI;EAC7G,yBAAyB,OAAM,UAC5B,MAAM,QAAQ,KAAK,SAAS,EAAA,EAAI,cAAc,SAAS,wBAAwB,IAAI;CACxF;AACF;;;;;AAMA,eAAsB,4BAA4B,MAKE;CAClD,IAAI,KAAK,WAAW;EAClB,MAAM,kBACJ,MAAM,QAAQ,IACZ,KAAK,eAAe,IAAI,OAAM,mBAAkB;GAC9C;GACA,SAAS,MAAM,cAAc,SAAS,eAAe,KAAK,SAAU;EACtE,EAAE,CACJ,EAAA,CACA,QAAO,UAAS,MAAM,YAAY,IAAI;EACxC,IAAI,eAAe,SAAS,GAAG,MAAM,IAAI,MAAM,8DAA8D;EAC7G,IAAI,eAAe,IAAI,OAAO,eAAe,EAAE,CAAC;CAClD;CAEA,MAAM,SAAS,CAAC;CAChB,KAAK,MAAM,iBAAiB,KAAK,gBAAgB;EAC/C,MAAM,cAAc,MAAM,cAAc,YAAY,KAAK;GACvD,OAAO,KAAK;GACZ,kBAAkB,KAAK;EACzB,CAAC;EACD,IAAI,sBAAsB;EAC1B,KAAK,MAAM,cAAc,aACvB,IAAI;GACF,KACG,MAAM,cAAc,oBAAoB,KAAK;IAAE,OAAO,KAAK;IAAO,cAAc,WAAW;GAAG,CAAC,EAAA,CAAG,SAAS,GAC5G;IACA,sBAAsB;IACtB;GACF;EACF,SAAS,OAAO;GACd,IAAI,EAAE,iBAAiB,uCAAuC,MAAM;EACtE;EAEF,IAAI,qBAAqB,OAAO,KAAK,aAAa;CACpD;CACA,IAAI,OAAO,SAAS,GAClB,MAAM,IAAI,kCACR,oFACF;CACF,OAAO,OAAO;AAChB;AA8BA,IAAa,sCAAb,cAAyD,MAAM;CACxC;CAArB,YAAY,QAA8C;EACxD,MACE,WAAW,eACP,iDACA,8CACN;EALmB,KAAA,SAAA;EAMnB,KAAK,OAAO;CACd;AACF;;;;;;;;AA2BA,eAAsB,+BAA+B,MAMV;CACzC,MAAM,EAAE,eAAe,OAAO,kBAAkB,mBAAmB;CAGnE,MAAM,cAAa,MADO,cAAc,YAAY,KAAK;EAAE;EAAO;CAAiB,CAAC,EAAA,CACrD,QAAO,cAAa,UAAU,kBAAkB,cAAc,aAAa;CAC1G,IAAI,WAAW,WAAW,GAAG,OAAO;EAAE,OAAO;EAAO,QAAQ;CAAa;CAMzE,KAAK,MAAM,cAAc,YAAY;EACnC,IAAI;EACJ,IAAI;GACF,MAAM,sBAAsB,MAAM,cAAc,oBAAoB,KAAK;IAAE;IAAO,cAAc,WAAW;GAAG,CAAC;GAO/G,YAAW,MANwB,QAAQ,IACzC,oBAAoB,IAAI,OAAM,uBAAsB;IAClD;IACA,YAAY,MAAM,cAAc,aAAa,IAAI;KAAE;KAAO,IAAI,kBAAkB;IAAa,CAAC;GAChG,EAAE,CACJ,EAAA,CACgC,MAC9B,cAAa,UAAU,eAAe,CAAC,kBAAkB,UAAU,WAAW,SAAS,eACzF;EACF,SAAS,OAAO;GAEd,IAAI,EAAE,iBAAiB,uCAAuC,MAAM;GACpE;EACF;EACA,IAAI,CAAC,UAAU,YAAY;EAE3B,OAAO;GACL,OAAO;GACP,qBAAqB,SAAS,kBAAkB;GAChD,YAAY,SAAS,kBAAkB,UAAU,SAAS,WAAW;GACrE,mBAAmB,WAAW;EAChC;CACF;CAEA,OAAO;EAAE,OAAO;EAAO,QAAQ;CAAa;AAC9C;;;;;;;;;;AAWA,eAAsB,gCAAgC,MAG0B;CAC9E,MAAM,EAAE,eAAe,cAAc;CAErC,MAAM,UAAU,MAAM,cAAc,SAAS,eAAe,SAAS;CACrE,IAAI,CAAC,SAAS,OAAO;CACrB,MAAM,oBAAoB,MAAM,cAAc,oBAAoB,IAAI;EACpE,OAAO,QAAQ;EACf,IAAI,QAAQ;CACd,CAAC;CACD,IAAI,CAAC,mBAAmB,OAAO;CAC/B,MAAM,aAAa,MAAM,cAAc,YAAY,IAAI;EAAE,OAAO,QAAQ;EAAO,IAAI,kBAAkB;CAAa,CAAC;CACnH,IAAI,CAAC,YAAY,OAAO;CAExB,OAAO;EAAE,kBAAkB,WAAW;EAAkB,OAAO,QAAQ;EAAO,QAAQ,QAAQ;CAAO;AACvG;;;;;;;;;;;;;;;;AAiBA,eAAsB,2BACpB,MACsC;CACtC,MAAM,EAAE,eAAe,OAAO,kBAAkB,QAAQ,mBAAmB;CAE3E,MAAM,WAAW,MAAM,+BAA+B;EAAE;EAAe;EAAO;EAAkB;CAAe,CAAC;CAChH,IAAI,CAAC,SAAS,OAAO,MAAM,IAAI,oCAAoC,SAAS,MAAM;CAElF,MAAM,SAAS,KAAK,qBAAqB,SAAS;CAClD,MAAM,UAAU,MAAM,cAAc,SAAS,OAAO;EAClD,WAAW,WAAW;EACtB,qBAAqB,SAAS;EAC9B;EACA;EACA;EACA,YAAY,SAAS;EACrB,YAAY;CACd,CAAC;CACD,OAAO;EACL,WAAW,QAAQ;EACnB;EACA,qBAAqB,SAAS;EAC9B,QAAQ,QAAQ;EAChB,YAAY,SAAS;CACvB;AACF;;;;;;;;;AA4BA,eAAsB,sBAAsB,SAAyB,MAAgD;CAGnH,MAAM,eAAe,SAAS,KAAK,KAAK;CACxC,IAAI;EACF,MAAM,SACJ,KAAK,kBAAkB,KAAK,mBACxB,MAAM,KAAK,eAAe,IAAI;GAC5B,OAAO,KAAK;GACZ,QAAQ,4BAA4B,KAAK,gBAAgB;EAC3D,CAAC,IACD;EAIN,MAAM,WAAW,KAAK,gBAAgB,MAAM,GAAG,CAAC,CAAC;EAEjD,MAAM,0BAA0B,SAAS,QADf,WAAW,yBAAyB,UAAU,KAAK,cAAc,CAAC,CAAC,UAAU,KAAA,CACrC;CACpE,SAAS,OAAO;EACd,QAAQ,KAAK,iEAAiE,EAC5E,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAC9D,CAAC;CACH;CACA,IAAI,KAAK,gBACP,IAAI;EACF,MAAM,QAAQ,MAAM,OAAO,EAAE,SAAS,KAAK,eAAe,CAAC;CAC7D,SAAS,OAAO;EACd,QAAQ,KAAK,yDAAyD;GACpE,SAAS,KAAK;GACd,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EAC9D,CAAC;CACH;AAEJ;;;;;;;;;;;;AAoBA,eAAsB,oCACpB,SACA,MACe;CACf,IAAI;EACF,MAAM,SAAS,MAAM,KAAK,eAAe,IAAI;GAC3C,OAAO,KAAK;GACZ,QAAQ,4BAA4B,KAAK,gBAAgB;EAC3D,CAAC;EACD,MAAM,UAAU,MAAM,KAAK,SAAS,IAAI;GAAE,OAAO,KAAK;GAAO,IAAI,KAAK;EAAiB,CAAC;EACxF,MAAM,WAAW,SAAS,gBAAgB,MAAM,GAAG,CAAC,CAAC;EAIrD,MAAM,0BAA0B,SAAS,QAHf,WACtB,yBAAyB,UAAU,SAAS,kBAAkB,KAAA,CAAS,CAAC,CAAC,UACzE,KAAA,CAC8D;CACpE,SAAS,OAAO;EACd,QAAQ,KAAK,uFAAuF,EAClG,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAC9D,CAAC;CACH;AACF"}
|
|
1
|
+
{"version":3,"file":"factory-session.js","names":[],"sources":["../../src/session/factory-session.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport { resolveProviderOMDefault } from '@mastra/code-sdk/onboarding/packs';\nimport type { MastraCodeState } from '@mastra/code-sdk/schema';\nimport type { AgentController } from '@mastra/core/agent-controller';\n\nimport { factoryMemorySettingsUserId } from '../storage/domains/memory-settings/base.js';\nimport type { MemorySettingsStorage } from '../storage/domains/memory-settings/base.js';\nimport type { FactoryProjectsStorage } from '../storage/domains/projects/base.js';\nimport {\n SourceControlConnectionNotFoundError,\n type SourceControlSession,\n type SourceControlStorageHandle,\n} from '../storage/domains/source-control/base.js';\nimport { applyStoredMemorySettings, type OMConfigurableSession } from './memory-settings-hydration.js';\nimport { seedSessionOrg } from './org-seed.js';\n\ntype FactorySession = Awaited<ReturnType<AgentController<MastraCodeState>['createSession']>>;\n\nexport class FactorySourceControlConflictError extends Error {}\n\n/**\n * Read the factory project's default model. Best-effort: a missing project or an\n * uninitialized storage domain means \"no default\", never a failed run.\n */\nexport async function resolveFactoryDefaultModelId(\n projects: FactoryProjectsStorage | undefined,\n factoryProjectId: string | undefined,\n): Promise<string | undefined> {\n if (!projects || !factoryProjectId) return undefined;\n try {\n const project = await projects.getById({ id: factoryProjectId });\n return project?.defaultModelId ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nexport interface SourceControlSessionLookup {\n getBySessionId(sessionId: string): Promise<SourceControlSession | null>;\n getSourceControlBySessionId(sessionId: string): Promise<SourceControlStorageHandle | null>;\n rename(args: { sessionId: string; title: string }): Promise<void>;\n markFirstMessage(args: { sessionId: string }): Promise<void>;\n markFirstMeaningfulExec(args: { sessionId: string }): Promise<void>;\n}\n\n/**\n * Read or update a session across every registered source-control partition.\n * Session ids are globally generated, so more than one match is invalid and\n * fails closed instead of mutating an arbitrary provider.\n */\nexport function createSourceControlSessionLookup(\n sourceControls: readonly SourceControlStorageHandle[],\n): SourceControlSessionLookup {\n const resolve = async (\n sessionId: string,\n ): Promise<{ sourceControl: SourceControlStorageHandle; session: SourceControlSession } | null> => {\n const matches = (\n await Promise.all(\n sourceControls.map(async sourceControl => ({\n sourceControl,\n session: await sourceControl.sessions.getBySessionId(sessionId),\n })),\n )\n ).filter(\n (match): match is { sourceControl: SourceControlStorageHandle; session: SourceControlSession } =>\n match.session !== null,\n );\n if (matches.length > 1) throw new Error('Factory session exists in multiple source-control providers.');\n return matches[0] ?? null;\n };\n\n return {\n getBySessionId: async sessionId => (await resolve(sessionId))?.session ?? null,\n getSourceControlBySessionId: async sessionId => (await resolve(sessionId))?.sourceControl ?? null,\n rename: async args => (await resolve(args.sessionId))?.sourceControl.sessions.rename(args),\n markFirstMessage: async args => (await resolve(args.sessionId))?.sourceControl.sessions.markFirstMessage(args),\n markFirstMeaningfulExec: async args =>\n (await resolve(args.sessionId))?.sourceControl.sessions.markFirstMeaningfulExec(args),\n };\n}\n\n/**\n * Resolve the source-control provider from durable Factory repository links,\n * never from the issue tracker that happened to create the work item.\n */\nexport async function resolveFactorySourceControl(args: {\n sourceControls: readonly SourceControlStorageHandle[];\n orgId: string;\n factoryProjectId: string;\n sessionId?: string;\n}): Promise<SourceControlStorageHandle | undefined> {\n if (args.sessionId) {\n const sessionMatches = (\n await Promise.all(\n args.sourceControls.map(async sourceControl => ({\n sourceControl,\n session: await sourceControl.sessions.getBySessionId(args.sessionId!),\n })),\n )\n ).filter(match => match.session !== null);\n if (sessionMatches.length > 1) throw new Error('Factory session exists in multiple source-control providers.');\n if (sessionMatches[0]) return sessionMatches[0].sourceControl;\n }\n\n const linked = [];\n for (const sourceControl of args.sourceControls) {\n const connections = await sourceControl.connections.list({\n orgId: args.orgId,\n factoryProjectId: args.factoryProjectId,\n });\n let hasLinkedRepository = false;\n for (const connection of connections) {\n try {\n if (\n (await sourceControl.projectRepositories.list({ orgId: args.orgId, connectionId: connection.id })).length > 0\n ) {\n hasLinkedRepository = true;\n break;\n }\n } catch (error) {\n if (!(error instanceof SourceControlConnectionNotFoundError)) throw error;\n }\n }\n if (hasLinkedRepository) linked.push(sourceControl);\n }\n if (linked.length > 1)\n throw new FactorySourceControlConflictError(\n 'Factory project has repositories linked through multiple source-control providers.',\n );\n return linked[0];\n}\n\nexport interface EnsureFactorySourceSessionArgs {\n /**\n * Storage handle of the integration that owns source control. Nothing here is\n * provider-specific: the connection is matched by the handle's own\n * `integrationId`, so GitHub, Slack-on-behalf-of-GitHub, or any future owner\n * all resolve through the same traversal.\n */\n sourceControl: SourceControlStorageHandle;\n orgId: string;\n factoryProjectId: string;\n branch: string;\n /** Pick the linked repository that the work item targets. */\n repositorySlug: string;\n /**\n * Attribute the run to this user instead of the repo connector. Set when the\n * run has an interactive user — e.g. the person who approved a proposed run.\n */\n attributeToUserId?: string;\n}\n\nexport interface EnsuredFactorySourceSession {\n sessionId: string;\n userId: string;\n projectRepositoryId: string;\n branch: string;\n baseBranch: string;\n}\n\nexport class FactorySourceSessionResolutionError extends Error {\n constructor(readonly reason: 'connection' | 'repository') {\n super(\n reason === 'connection'\n ? 'Factory source-control connection not found.'\n : 'Factory source-control repository not found.',\n );\n this.name = 'FactorySourceSessionResolutionError';\n }\n}\n\nexport interface ResolvedFactorySourceRepository {\n projectRepositoryId: string;\n /** The repository's pinned branch, else its default branch. */\n baseBranch: string;\n /** Who connected the repository. The attribution for runs with no interactive user. */\n connectedByUserId: string;\n}\n\n/**\n * Outcome of {@link resolveFactorySourceRepository}. A miss carries which step\n * failed: callers differ on whether that is an error (an autonomous run cannot\n * proceed) or a routine fallback (a chat integration drops to a chat-only\n * session), and the two steps fail for different reasons worth reporting apart.\n */\nexport type FactorySourceRepositoryResult =\n | ({ found: true } & ResolvedFactorySourceRepository)\n | { found: false; reason: 'connection' | 'repository' };\n\n/**\n * Resolve which repository a factory project's source-control runs act on: the\n * owner's connection on the project, then one of its linked repositories.\n *\n * The owner is whichever integration owns source control, matched by the\n * handle's own `integrationId` — nothing here is provider-specific.\n */\nexport async function resolveFactorySourceRepository(\n args:\n | {\n sourceControl: SourceControlStorageHandle;\n orgId: string;\n factoryProjectId: string;\n repositorySlug: string;\n }\n | {\n sourceControl: SourceControlStorageHandle;\n orgId: string;\n factoryProjectId: string;\n firstLinkedRepository: true;\n },\n): Promise<FactorySourceRepositoryResult> {\n const { sourceControl, orgId, factoryProjectId } = args;\n const repositorySlug = 'repositorySlug' in args ? args.repositorySlug : undefined;\n const firstLinkedRepository = 'firstLinkedRepository' in args;\n\n const connections = await sourceControl.connections.list({ orgId, factoryProjectId });\n const candidates = connections.filter(candidate => candidate.integrationId === sourceControl.integrationId);\n if (candidates.length === 0) return { found: false, reason: 'connection' };\n\n // A project can carry stale connections: a provider-app reinstall leaves the\n // old connection pointing at an installation that no longer exists, and that\n // row can sit ahead of the healthy one. Try every candidate and skip the ones\n // that no longer resolve rather than failing on the first.\n for (const connection of candidates) {\n let resolved;\n try {\n const projectRepositories = await sourceControl.projectRepositories.list({ orgId, connectionId: connection.id });\n const resolvedRepositories = await Promise.all(\n projectRepositories.map(async projectRepository => ({\n projectRepository,\n repository: await sourceControl.repositories.get({ orgId, id: projectRepository.repositoryId }),\n })),\n );\n resolved = resolvedRepositories.find(\n candidate => candidate.repository && (firstLinkedRepository || candidate.repository.slug === repositorySlug),\n );\n } catch (error) {\n // A deleted installation invalidates a stale connection; storage failures must propagate.\n if (!(error instanceof SourceControlConnectionNotFoundError)) throw error;\n continue;\n }\n if (!resolved?.repository) continue;\n\n return {\n found: true,\n projectRepositoryId: resolved.projectRepository.id,\n baseBranch: resolved.projectRepository.branch ?? resolved.repository.defaultBranch,\n connectedByUserId: connection.createdByUserId,\n };\n }\n\n return { found: false, reason: 'repository' };\n}\n\n/**\n * Walk a Factory user-session id back to the project it belongs to.\n *\n * Repo-backed channel threads are keyed by their Factory session id, which is\n * the only handle a session-start hook gets. This turns that id back into the\n * project whose configuration the session should adopt. Durable by\n * construction — it reads the same rows the session was created from, so it\n * survives restarts without any in-memory mapping.\n */\nexport async function resolveFactoryProjectForSession(args: {\n sourceControl: SourceControlStorageHandle;\n sessionId: string;\n}): Promise<{ factoryProjectId: string; orgId: string; userId: string } | null> {\n const { sourceControl, sessionId } = args;\n\n const session = await sourceControl.sessions.getBySessionId(sessionId);\n if (!session) return null;\n const projectRepository = await sourceControl.projectRepositories.get({\n orgId: session.orgId,\n id: session.projectRepositoryId,\n });\n if (!projectRepository) return null;\n const connection = await sourceControl.connections.get({ orgId: session.orgId, id: projectRepository.connectionId });\n if (!connection) return null;\n\n return { factoryProjectId: connection.factoryProjectId, orgId: session.orgId, userId: session.userId };\n}\n\n/**\n * Create the source-control session a repo-backed factory run needs.\n *\n * `FactoryStartCoordinator.prepare` requires this record to already exist —\n * `resolveSourceSession` throws `Factory session not found` otherwise — so every\n * autonomous entry point has to produce one before it can start a run. This is\n * that step, in one place: the owner's connection on the factory project, one of\n * its linked repositories, and a session on the requested branch with the\n * repository's pinned or default branch as the base.\n *\n * The run is attributed to `attributeToUserId` when the caller has an\n * interactive user (e.g. the approver of a proposed run), and otherwise falls\n * back to whoever connected the repository (`connection.createdByUserId`),\n * because a genuinely autonomous run has no interactive user of its own.\n */\nexport async function ensureFactorySourceSession(\n args: EnsureFactorySourceSessionArgs,\n): Promise<EnsuredFactorySourceSession> {\n const { sourceControl, orgId, factoryProjectId, branch, repositorySlug } = args;\n\n const resolved = await resolveFactorySourceRepository({ sourceControl, orgId, factoryProjectId, repositorySlug });\n if (!resolved.found) throw new FactorySourceSessionResolutionError(resolved.reason);\n\n const userId = args.attributeToUserId ?? resolved.connectedByUserId;\n const session = await sourceControl.sessions.create({\n sessionId: randomUUID(),\n projectRepositoryId: resolved.projectRepositoryId,\n orgId,\n userId,\n branch,\n baseBranch: resolved.baseBranch,\n visibility: 'org',\n });\n return {\n sessionId: session.sessionId,\n userId,\n projectRepositoryId: resolved.projectRepositoryId,\n branch: session.branch,\n baseBranch: resolved.baseBranch,\n };\n}\n\nexport interface HydrateFactorySessionArgs {\n orgId: string;\n /**\n * The factory project whose shared memory settings apply. Factory sessions\n * never read an individual user's personal memory settings — the project's\n * own row (or the built-in defaults) is what they run with.\n */\n factoryProjectId?: string;\n /** The factory project's default model. Without it the session keeps the SDK's built-in mode default. */\n defaultModelId?: string;\n /**\n * When provided, the factory project's stored memory-settings row is\n * applied. When omitted (or no row exists) the session is reset to the\n * built-in memory defaults.\n */\n memorySettings?: MemorySettingsStorage;\n}\n\n/**\n * Apply a factory project's configuration to a freshly created session:\n * observational-memory settings, then the project's default model.\n *\n * Both steps are best-effort. A retired model id or an unreachable settings row\n * must not sink a run that is otherwise ready — the session simply keeps the\n * default it was created with, and the reason is logged.\n */\nexport async function hydrateFactorySession(session: FactorySession, args: HydrateFactorySessionArgs): Promise<void> {\n // The org rung knowledge curation scopes on. Seeded first so it lands even if\n // a later best-effort step fails; an empty org marks the session unresolved.\n await seedSessionOrg(session, args.orgId);\n try {\n const record =\n args.memorySettings && args.factoryProjectId\n ? await args.memorySettings.get({\n orgId: args.orgId,\n userId: factoryMemorySettingsUserId(args.factoryProjectId),\n })\n : null;\n // Without a stored row, fall back to the low-cost OM model of the factory\n // default model's provider — a factory connected only to Anthropic should\n // not observe with the (uncredentialed) built-in Google default.\n const provider = args.defaultModelId?.split('/')[0];\n const fallbackOmModelId = provider ? resolveProviderOMDefault(provider, args.defaultModelId).modelId : undefined;\n await applyStoredMemorySettings(session, record, fallbackOmModelId);\n } catch (error) {\n console.warn('[Factory Start] Failed to apply observational-memory settings', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n if (args.defaultModelId) {\n try {\n await session.model.switch({ modelId: args.defaultModelId });\n } catch (error) {\n console.warn('[Factory Start] Failed to apply factory default model', {\n modelId: args.defaultModelId,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n}\n\nexport interface RefreshFactorySessionMemorySettingsArgs {\n orgId: string;\n factoryProjectId: string;\n projects: Pick<FactoryProjectsStorage, 'get'>;\n memorySettings: Pick<MemorySettingsStorage, 'get'>;\n}\n\n/**\n * Re-apply a factory project's stored observational-memory settings to an\n * already-running session that automation is about to reuse. Session creation\n * hydrates these settings once (`hydrateFactorySession`), but a reused binding\n * keeps whatever observer/reflector models it was created with — so a project\n * whose OM models changed since would keep observing with the stale (and\n * possibly since-rejected) models. This reads the project's current row with the\n * same provider-aware fallback as initial hydration and applies it, mirroring\n * the `GET /web/config/om` refresh. Best-effort: a settings lookup failure must\n * never sink an otherwise-ready run, so it is logged and swallowed.\n */\nexport async function refreshFactorySessionMemorySettings(\n session: OMConfigurableSession,\n args: RefreshFactorySessionMemorySettingsArgs,\n): Promise<void> {\n try {\n const record = await args.memorySettings.get({\n orgId: args.orgId,\n userId: factoryMemorySettingsUserId(args.factoryProjectId),\n });\n const project = await args.projects.get({ orgId: args.orgId, id: args.factoryProjectId });\n const provider = project?.defaultModelId?.split('/')[0];\n const fallbackOmModelId = provider\n ? resolveProviderOMDefault(provider, project?.defaultModelId ?? undefined).modelId\n : undefined;\n await applyStoredMemorySettings(session, record, fallbackOmModelId);\n } catch (error) {\n console.warn('[Factory dispatch] Failed to reapply observational-memory settings on session reuse', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type SourceControlStorageHandle } from '../storage/domains/source-control/base.js';
|
|
2
|
+
import type { WorkItemRow } from '../storage/domains/work-items/base.js';
|
|
3
|
+
export type WorkItemRepositoryResolution = {
|
|
4
|
+
status: 'resolved';
|
|
5
|
+
projectRepositoryId: string;
|
|
6
|
+
slug: string;
|
|
7
|
+
} | {
|
|
8
|
+
status: 'unlinked';
|
|
9
|
+
hint: string;
|
|
10
|
+
} | {
|
|
11
|
+
status: 'ambiguous';
|
|
12
|
+
candidates: string[];
|
|
13
|
+
};
|
|
14
|
+
export declare function resolveWorkItemRepository(args: {
|
|
15
|
+
sourceControl: SourceControlStorageHandle;
|
|
16
|
+
orgId: string;
|
|
17
|
+
factoryProjectId: string;
|
|
18
|
+
item: Pick<WorkItemRow, 'metadata'>;
|
|
19
|
+
linearRepositoryMap?: Record<string, string>;
|
|
20
|
+
}): Promise<WorkItemRepositoryResolution>;
|
|
21
|
+
//# sourceMappingURL=work-item-repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"work-item-repository.d.ts","sourceRoot":"","sources":["../../src/session/work-item-repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAEzE,MAAM,MAAM,4BAA4B,GACpC;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,mBAAmB,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjE;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAQlD,wBAAsB,yBAAyB,CAAC,IAAI,EAAE;IACpD,aAAa,EAAE,0BAA0B,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACpC,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9C,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAsExC"}
|