tycono 0.1.59 → 0.1.60
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/package.json +1 -1
- package/src/api/src/engine/context-assembler.ts +11 -0
- package/src/api/src/services/job-manager.ts +21 -1
- package/src/web/dist/assets/index-B_9y4WxJ.js +101 -0
- package/src/web/dist/assets/{preview-app-Dxb6NBei.js → preview-app-DxNB7Wdm.js} +1 -1
- package/src/web/dist/index.html +1 -1
- package/src/web/dist/assets/index-Jayn_T3T.js +0 -101
package/package.json
CHANGED
|
@@ -112,6 +112,17 @@ export function assembleContext(
|
|
|
112
112
|
// Dispatch 도구 안내 (하위 Role이 있는 경우)
|
|
113
113
|
if (subordinates.length > 0) {
|
|
114
114
|
sections.push(buildDispatchSection(orgTree, roleId, subordinates, options?.teamStatus));
|
|
115
|
+
} else if (node.level === 'c-level') {
|
|
116
|
+
// C-level with no subordinates — clarify authority boundaries
|
|
117
|
+
sections.push(`# Team Structure
|
|
118
|
+
|
|
119
|
+
⚠️ **You have no direct reports.** You are an individual contributor at the C-level.
|
|
120
|
+
|
|
121
|
+
- You CANNOT dispatch tasks to other roles (no subordinates)
|
|
122
|
+
- You CAN consult other roles for information (see Consult section below)
|
|
123
|
+
- You MUST do the work yourself — research, analyze, write, decide
|
|
124
|
+
- If implementation requires another role (e.g., engineering work), recommend it to CEO
|
|
125
|
+
- Make decisions within your authority autonomously — do NOT ask CEO for decisions you can make yourself`);
|
|
115
126
|
}
|
|
116
127
|
|
|
117
128
|
// Consult 도구 안내 (상담 가능한 Role이 있는 경우)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { COMPANY_ROOT } from './file-reader.js';
|
|
2
2
|
import { ActivityStream, type ActivityEvent } from './activity-stream.js';
|
|
3
3
|
import { buildOrgTree } from '../engine/org-tree.js';
|
|
4
|
+
import { validateDispatch, validateConsult } from '../engine/authority-validator.js';
|
|
4
5
|
import { createRunner } from '../engine/runners/index.js';
|
|
5
6
|
import type { ExecutionRunner } from '../engine/runners/types.js';
|
|
6
7
|
import { setActivity, updateActivity, completeActivity } from './activity-tracker.js';
|
|
@@ -117,11 +118,30 @@ class JobManager {
|
|
|
117
118
|
return () => { this.jobCreatedListeners.delete(listener); };
|
|
118
119
|
}
|
|
119
120
|
|
|
120
|
-
/** Start a new execution job. Returns the Job immediately (fire-and-forget).
|
|
121
|
+
/** Start a new execution job. Returns the Job immediately (fire-and-forget).
|
|
122
|
+
* Throws if sourceRole lacks authority to dispatch/consult the target role. */
|
|
121
123
|
startJob(params: StartJobParams): Job {
|
|
122
124
|
const jobId = `job-${Date.now()}-${this.nextId++}`;
|
|
123
125
|
const orgTree = buildOrgTree(COMPANY_ROOT);
|
|
124
126
|
|
|
127
|
+
// Authority gate: validate dispatch/consult authority at job creation
|
|
128
|
+
if (params.sourceRole && params.sourceRole !== 'ceo') {
|
|
129
|
+
if (params.type === 'consult') {
|
|
130
|
+
const auth = validateConsult(orgTree, params.sourceRole, params.roleId);
|
|
131
|
+
if (!auth.allowed) {
|
|
132
|
+
console.warn(`[JobManager] Authority denied: ${params.sourceRole} → ${params.roleId} (consult): ${auth.reason}`);
|
|
133
|
+
throw new Error(`Authority denied: ${auth.reason}`);
|
|
134
|
+
}
|
|
135
|
+
} else if (params.type === 'assign' && params.parentJobId) {
|
|
136
|
+
// Only validate dispatch authority for child jobs (not CEO waves)
|
|
137
|
+
const auth = validateDispatch(orgTree, params.sourceRole, params.roleId);
|
|
138
|
+
if (!auth.allowed) {
|
|
139
|
+
console.warn(`[JobManager] Authority denied: ${params.sourceRole} → ${params.roleId} (dispatch): ${auth.reason}`);
|
|
140
|
+
throw new Error(`Authority denied: ${auth.reason}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
125
145
|
const stream = new ActivityStream(jobId, params.roleId, params.parentJobId);
|
|
126
146
|
|
|
127
147
|
const job: Job = {
|