Harden recovery and department paths after adversarial review

Interrupted runs now return to the queue instead of failing - an app
shutdown is not a model error and must not spend the task's bounded
retry budget. Startup work moves behind the single-instance lock so a
losing second instance can never run recovery against the live
instance's database. Background provider requests that died before
receiving an external response id now fail at boot (the background
worker can only resume accepted ones). Agent updates resolve the
department through the same canonical lookup as hires, replacing the
free-text write and its invented "General" default.
This commit is contained in:
ZacharyZhang-NY committed 2026-06-09 21:36:18 -04:00
1 parent b4e17cbd35
commit 921c5b4456
5 files changed
+106 -89

No files matched your search

@@ -26,20 +26,30 @@ export class OrgGovernanceService {
`).run(createId("arr"), orgId, "*", RISK_LEVEL.LOW, ROUTE_TO_TYPE.EMPLOYEE, boardEmployeeId, now);
}
enforceHiringPolicy(input: CreateAgentInput): HiringPolicyDecision {
const requested = input.department.trim();
/** Resolves the canonical department name (case-insensitive), or throws naming the valid choices. */
requireCanonicalDepartment(orgId: string, department: string): string {
const requested = department.trim();
if (!requested) throw new Error("Department is required.");
const policy = this.db.prepare(`
select department_name, max_headcount, monthly_budget_limit_cents, require_approval_above_cents
from hiring_policies
const row = this.db.prepare(`
select department_name from hiring_policies
where org_id = ? and lower(department_name) = lower(?)
`).get(input.orgId, requested) as HiringPolicyRow | undefined;
if (!policy) {
`).get(orgId, requested) as { department_name: string } | undefined;
if (!row) {
const known = this.db.prepare("select department_name from hiring_policies where org_id = ? order by department_name asc")
.all(input.orgId) as Array<{ department_name: string }>;
throw new Error(`Unknown department "${requested}". Departments: ${known.map((row) => row.department_name).join(", ")}.`);
.all(orgId) as Array<{ department_name: string }>;
throw new Error(`Unknown department "${requested}". Departments: ${known.map((entry) => entry.department_name).join(", ")}.`);
}
const departmentName = policy.department_name;
return row.department_name;
}
enforceHiringPolicy(input: CreateAgentInput): HiringPolicyDecision {
const departmentName = this.requireCanonicalDepartment(input.orgId, input.department);
const policy = this.db.prepare(`
select max_headcount, monthly_budget_limit_cents, require_approval_above_cents
from hiring_policies
where org_id = ? and department_name = ?
`).get(input.orgId, departmentName) as HiringPolicyRow | undefined;
if (!policy) throw new Error("Hiring policy is required for department.");
const usage = this.db.prepare(`
select count(*) as headcount, coalesce(sum(budget_cents), 0) as budget_cents
from agents
@@ -126,7 +136,6 @@ export class OrgGovernanceService {
}
interface HiringPolicyRow {
department_name: string;
max_headcount: number;
monthly_budget_limit_cents: number;
require_approval_above_cents: number;
@@ -200,7 +200,7 @@ export class OrganizationService {
input.orgId,
"agent_hire",
`Review hire: ${input.name.trim()}`,
`Department: ${input.department.trim()}\nRole: ${input.role.trim()}\nBudget: ${input.budgetCents}`,
`Department: ${hiringPolicy.departmentName}\nRole: ${input.role.trim()}\nBudget: ${input.budgetCents}`,
RISK_LEVEL.MEDIUM,
"system",
null,
@@ -228,13 +228,13 @@ export class OrganizationService {
.get(input.modelProviderId, input.orgId) as { id: string } | undefined;
if (!provider) throw new Error("Agent provider was not found.");
}
const department = input.department.trim();
const department = this.governance.requireCanonicalDepartment(input.orgId, input.department);
const budgetCents = Math.max(0, Math.round(input.budgetCents));
const result = this.db.prepare(`
update agents
set role = ?, title = ?, role_level = ?, department = ?, budget_cents = ?, model_provider_id = ?, model_id = ?
where id = ? and org_id = ?
`).run(role, input.title.trim() || role, input.roleLevel.trim() || "staff", department || "General", budgetCents, input.modelProviderId, input.modelId, input.agentId, input.orgId);
`).run(role, input.title.trim() || role, input.roleLevel.trim() || "staff", department, budgetCents, input.modelProviderId, input.modelId, input.agentId, input.orgId);
if (result.changes === 0) throw new Error("Agent update failed.");
this.audit.record({
orgId: input.orgId,