mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-23 00:53:38 +02:00
Default new hires to approved
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
f985b38c62
commit
b522672423
7 files changed
+45
-11
No files matched your search
@@ -47,7 +47,7 @@ You do **not** need to tell the CEO to engage specific agents. After you approve
|
||||
- **Breaks goals into concrete tasks** with clear descriptions, priorities, and acceptance criteria
|
||||
- **Assigns tasks to the right agent** based on role and capabilities (e.g., engineering tasks go to the CTO or engineers, marketing tasks go to the CMO)
|
||||
- **Creates subtasks** when work needs to be decomposed further
|
||||
- **Hires new agents** when the team lacks capacity for a goal (subject to your approval)
|
||||
- **Hires new agents** when the team lacks capacity for a goal, with hire approvals available when enabled in company settings
|
||||
- **Monitors progress** on each heartbeat, checking task status and unblocking reports
|
||||
- **Escalates to you** when it encounters something it can't resolve — budget issues, blocked approvals, or strategic ambiguity
|
||||
|
||||
|
||||
@@ -57,9 +57,9 @@ The CEO is the primary delegator. When you set company goals, the CEO:
|
||||
1. Creates a strategy and submits it for your approval
|
||||
2. Breaks approved goals into tasks
|
||||
3. Assigns tasks to agents based on their role and capabilities
|
||||
4. Hires new agents when needed (subject to your approval)
|
||||
4. Hires new agents when needed, with hire approvals available when you enable them
|
||||
|
||||
You don't need to manually assign every task — set the goals and let the CEO organize the work. You approve key decisions (strategy, hiring) and monitor progress. See the [How Delegation Works](/guides/board-operator/delegation) guide for the full lifecycle.
|
||||
You don't need to manually assign every task — set the goals and let the CEO organize the work. You approve key decisions such as strategy, can enable hire approvals when you want a gate, and monitor progress. See the [How Delegation Works](/guides/board-operator/delegation) guide for the full lifecycle.
|
||||
|
||||
## Heartbeats
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE "companies" ALTER COLUMN "require_board_approval_for_new_agents" SET DEFAULT false;
|
||||
@@ -498,6 +498,13 @@
|
||||
"when": 1776780004000,
|
||||
"tag": "0070_active_run_output_watchdog",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 71,
|
||||
"version": "7",
|
||||
"when": 1777131234000,
|
||||
"tag": "0071_default_hire_approval_off",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -15,7 +15,7 @@ export const companies = pgTable(
|
||||
spentMonthlyCents: integer("spent_monthly_cents").notNull().default(0),
|
||||
requireBoardApprovalForNewAgents: boolean("require_board_approval_for_new_agents")
|
||||
.notNull()
|
||||
.default(true),
|
||||
.default(false),
|
||||
feedbackDataSharingEnabled: boolean("feedback_data_sharing_enabled")
|
||||
.notNull()
|
||||
.default(false),
|
||||
|
||||
@@ -139,12 +139,12 @@ describe("company portability", () => {
|
||||
brandColor: "#5c5fff",
|
||||
logoAssetId: null,
|
||||
logoUrl: null,
|
||||
requireBoardApprovalForNewAgents: true,
|
||||
requireBoardApprovalForNewAgents: false,
|
||||
});
|
||||
companySvc.create.mockResolvedValue({
|
||||
id: "company-imported",
|
||||
name: "Imported Paperclip",
|
||||
requireBoardApprovalForNewAgents: true,
|
||||
requireBoardApprovalForNewAgents: false,
|
||||
});
|
||||
agentSvc.list.mockResolvedValue([
|
||||
{
|
||||
@@ -461,6 +461,32 @@ describe("company portability", () => {
|
||||
expect(exported.warnings).toContain("Agent claudecoder PATH override was omitted from export because it is system-dependent.");
|
||||
});
|
||||
|
||||
it("exports hire approval policy only when approval is required", async () => {
|
||||
const portability = companyPortabilityService({} as any);
|
||||
|
||||
companySvc.getById.mockResolvedValueOnce({
|
||||
id: "company-1",
|
||||
name: "Paperclip",
|
||||
description: null,
|
||||
issuePrefix: "PAP",
|
||||
brandColor: "#5c5fff",
|
||||
logoAssetId: null,
|
||||
logoUrl: null,
|
||||
requireBoardApprovalForNewAgents: true,
|
||||
});
|
||||
|
||||
const exported = await portability.exportBundle("company-1", {
|
||||
include: {
|
||||
company: true,
|
||||
agents: false,
|
||||
projects: false,
|
||||
issues: false,
|
||||
},
|
||||
});
|
||||
|
||||
expect(asTextFile(exported.files[".paperclip.yaml"])).toContain("requireBoardApprovalForNewAgents: true");
|
||||
});
|
||||
|
||||
it("exports default sidebar order into the Paperclip extension and manifest", async () => {
|
||||
const portability = companyPortabilityService({} as any);
|
||||
|
||||
@@ -2554,7 +2580,7 @@ describe("company portability", () => {
|
||||
status: "idle",
|
||||
}));
|
||||
expect(companySvc.create).toHaveBeenCalledWith(expect.objectContaining({
|
||||
requireBoardApprovalForNewAgents: true,
|
||||
requireBoardApprovalForNewAgents: false,
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
@@ -2264,7 +2264,7 @@ function buildEnvInputMap(inputs: CompanyPortabilityEnvInput[]) {
|
||||
}
|
||||
|
||||
function readCompanyApprovalDefault(_frontmatter: Record<string, unknown>) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function readIncludeEntries(frontmatter: Record<string, unknown>): CompanyPackageIncludeEntry[] {
|
||||
@@ -3465,7 +3465,7 @@ export function companyPortabilityService(db: Db, storage?: StorageService) {
|
||||
company: stripEmptyValues({
|
||||
brandColor: company.brandColor ?? null,
|
||||
logoPath: companyLogoPath,
|
||||
requireBoardApprovalForNewAgents: company.requireBoardApprovalForNewAgents ? undefined : false,
|
||||
requireBoardApprovalForNewAgents: company.requireBoardApprovalForNewAgents ? true : undefined,
|
||||
feedbackDataSharingEnabled: company.feedbackDataSharingEnabled ? true : undefined,
|
||||
feedbackDataSharingConsentAt: company.feedbackDataSharingConsentAt?.toISOString() ?? null,
|
||||
feedbackDataSharingConsentByUserId: company.feedbackDataSharingConsentByUserId ?? null,
|
||||
@@ -3986,8 +3986,8 @@ export function companyPortabilityService(db: Db, storage?: StorageService) {
|
||||
description: include.company ? (sourceManifest.company?.description ?? null) : null,
|
||||
brandColor: include.company ? (sourceManifest.company?.brandColor ?? null) : null,
|
||||
requireBoardApprovalForNewAgents: include.company
|
||||
? (sourceManifest.company?.requireBoardApprovalForNewAgents ?? true)
|
||||
: true,
|
||||
? (sourceManifest.company?.requireBoardApprovalForNewAgents ?? false)
|
||||
: false,
|
||||
feedbackDataSharingEnabled: include.company
|
||||
? (sourceManifest.company?.feedbackDataSharingEnabled ?? false)
|
||||
: false,
|
||||
|
||||
Reference in new issue
Block a user