Show cross-department contacts to every role

The department map was only rendered for CEOs and managers, and IC
operating instructions framed communication as "DM your manager". The
combined effect: individual contributors had no knowledge of who leads
the other departments and no explicit permission to DM them —
coordination funnelled through the CEO, one-way.

Render the department map for every agent (leads-only for ICs to keep
the prefix lean) and extend the IC authority list + proactive-comms
section to authorise direct cross-department DMs. The CEO's role
becomes orchestration-by-exception rather than a serialised inbox.
This commit is contained in:
ZacharyZhang-NY committed 2026-04-19 19:19:38 -04:00
1 parent a3006f0b38
commit 74ae5e922b
2 files changed
+24 -14

No files matched your search

@@ -164,6 +164,7 @@ When your task is set back to "in_progress" with feedback:
- When completing a significant milestone, post a progress comment even if not required
- If you discover something unexpected, comment immediately — don't wait
- When creating subtasks for yourself, comment on the parent explaining your breakdown
- You are authorised to DM any peer directly — including leads in other departments listed in the Company Department Map — when their expertise unblocks your work. Do not funnel every cross-department question through your manager.
- If you notice a task could benefit from another agent's input, send them a message:
POST /api/companies/${companyId}/messages with channel "direct"
- After solving a tricky problem, add it to the knowledge base:
@@ -218,7 +219,7 @@ export const authorityRules: Record<AuthorityLevel, string[]> = {
"Submit work for review (in_review status)",
"Post comments on tasks you're involved with",
"Request approvals when blocked (secret_access, etc.)",
"Send messages to your manager and teammates",
"Send direct messages to your manager, teammates, and any cross-department lead listed in the Company Department Map",
"Create knowledge base entries from your learnings",
"Create documents relevant to your work (specs, post-mortems)",
"Report blockers and escalate to your manager",
+22 -13
View File
@@ -142,20 +142,29 @@ export function buildSystemPrompt(ctx: PromptContext): string {
sections.push(m.departmentMembersSection(deptLabel, memberLines));
}
if (isCEO || ctx.directReports.length > 0) {
const deptMap = new Map<string, typeof ctx.allAgents>();
for (const a of ctx.allAgents.filter((a) => a.status !== "terminated")) {
const dept = a.department ?? "unassigned";
if (!deptMap.has(dept)) deptMap.set(dept, []);
deptMap.get(dept)!.push(a);
}
if (deptMap.size > 1) {
const deptLines = Array.from(deptMap.entries()).map(([dept, members]) => {
const label = DEPARTMENT_LABELS[dept as DepartmentId] ?? dept;
// Every agent needs to see where the other departments' entry points
// are so DMs can cross the org without going through the CEO. Leads
// (CEO + managers) get the full member roll call; individual
// contributors get the single lead per department so their prompt
// stays lean while still enabling direct cross-dept reach-out.
const deptMap = new Map<string, typeof ctx.allAgents>();
for (const a of ctx.allAgents.filter((a) => a.status !== "terminated")) {
const dept = a.department ?? "unassigned";
if (!deptMap.has(dept)) deptMap.set(dept, []);
deptMap.get(dept)!.push(a);
}
if (deptMap.size > 1) {
const showAllMembers = isCEO || isManager;
const deptLines = Array.from(deptMap.entries()).map(([dept, members]) => {
const label = DEPARTMENT_LABELS[dept as DepartmentId] ?? dept;
if (showAllMembers) {
return m.companyDeptMapLine(label, members.length, members.map((x) => x.name).join(", "));
}).join("\n");
sections.push(m.companyDepartmentMapSection(deptLines));
}
}
const leads = members.filter((x) => !x.reportsTo || ctx.directReports.every((r) => r.id !== x.id));
const leadNames = (leads.length > 0 ? leads : members).slice(0, 3).map((x) => x.name).join(", ");
return m.companyDeptMapLine(label, members.length, leadNames);
}).join("\n");
sections.push(m.companyDepartmentMapSection(deptLines));
}
const activeGoals = ctx.goals.filter((g) => g.status === "active" || g.status === "planned");