@kernloop/faculty-workforce 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 William Zujkowski and Kernloop contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,77 @@
1
+ /**
2
+ * PM plan decomposition — the MECHANICAL half (spec §5.4; CLM-0041).
3
+ *
4
+ * The split: a PM model WRITES the subtask specs upstream, through an
5
+ * invoke function the composition root binds to the kernel adapters; this
6
+ * function never calls a model. It takes those specs as plain input and
7
+ * enforces the contract: schema validity, id/parent/overlay derivation,
8
+ * ceiling clamping, and the budget-sum invariant. The invariant is therefore
9
+ * unit-testable without any model in the loop.
10
+ */
11
+ import { type TaskContract } from '@kernloop/contracts';
12
+ import { z } from 'zod';
13
+ /**
14
+ * One subtask as proposed by the PM. Identity, overlay, and authority are
15
+ * NOT inputs — they are derived from the parent here, so a PM cannot grant
16
+ * what the parent does not hold.
17
+ */
18
+ export declare const SubtaskSpecSchema: z.ZodObject<{
19
+ goal: z.ZodString;
20
+ constraints: z.ZodOptional<z.ZodArray<z.ZodString>>;
21
+ budget: z.ZodObject<{
22
+ tokens: z.ZodNumber;
23
+ usd: z.ZodNumber;
24
+ wallClockMin: z.ZodNumber;
25
+ }, z.core.$strict>;
26
+ evidence: z.ZodOptional<z.ZodArray<z.ZodObject<{
27
+ kind: z.ZodEnum<{
28
+ test: "test";
29
+ ci: "ci";
30
+ doc: "doc";
31
+ eval: "eval";
32
+ }>;
33
+ ref: z.ZodString;
34
+ }, z.core.$strict>>>;
35
+ definitionOfDone: z.ZodOptional<z.ZodArray<z.ZodObject<{
36
+ name: z.ZodString;
37
+ command: z.ZodString;
38
+ }, z.core.$strict>>>;
39
+ assignTo: z.ZodEnum<{
40
+ pm: "pm";
41
+ coder: "coder";
42
+ reviewer: "reviewer";
43
+ documenter: "documenter";
44
+ researcher: "researcher";
45
+ }>;
46
+ }, z.core.$strict>;
47
+ export type SubtaskSpec = z.infer<typeof SubtaskSpecSchema>;
48
+ /** Input to {@link decomposePlan}. */
49
+ export interface DecomposePlanInput {
50
+ parent: TaskContract;
51
+ subtasks: SubtaskSpec[];
52
+ }
53
+ /**
54
+ * Derive zod-valid child TaskContracts from a parent plus PM-proposed
55
+ * subtask specs, enforcing (CLM-0041):
56
+ *
57
+ * - BUDGET INVARIANT: child budgets sum within the parent's on each of
58
+ * tokens, usd, and wallClockMin independently; any breach throws
59
+ * {@link BudgetExceededError} naming the dimension and amounts. An exact
60
+ * sum is within budget. Zero/negative child slices are rejected.
61
+ * - Identity: `child.id = parent.id + '.<n>'` (1-based input order),
62
+ * `child.parent = parent.id`, `child.overlay = parent.overlay`.
63
+ * - Authority: `child.authorityCeiling = min(parent ceiling, 'suggest')`.
64
+ * Children NEVER exceed the parent ceiling, and agent work is generative,
65
+ * so it is additionally clamped at the `suggest` entry tier (spec §3.2);
66
+ * the spec is silent on per-child explicit ceilings, so none is accepted
67
+ * — a PM cannot grant authority (narrowest reading, recorded).
68
+ * - Constraints: parent constraints bind children, so each child inherits
69
+ * them, followed by the subtask's own constraints, followed by a routing
70
+ * constraint `assign:agent.<template>` naming the assigned template's
71
+ * capability.
72
+ *
73
+ * Fan-out parallelism is bounded by the parent budget as a consequence: the
74
+ * kernel meters, the PM allocates (spec §5.4).
75
+ */
76
+ export declare function decomposePlan(input: DecomposePlanInput): TaskContract[];
77
+ //# sourceMappingURL=decompose.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decompose.d.ts","sourceRoot":"","sources":["../src/decompose.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAkC,KAAK,YAAY,EAAa,MAAM,qBAAqB,CAAC;AACnG,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAuBxB;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAQ5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,sCAAsC;AACtC,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,YAAY,CAAC;IACrB,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAqBD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,YAAY,EAAE,CAyBvE"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * PM plan decomposition — the MECHANICAL half (spec §5.4; CLM-0041).
3
+ *
4
+ * The split: a PM model WRITES the subtask specs upstream, through an
5
+ * invoke function the composition root binds to the kernel adapters; this
6
+ * function never calls a model. It takes those specs as plain input and
7
+ * enforces the contract: schema validity, id/parent/overlay derivation,
8
+ * ceiling clamping, and the budget-sum invariant. The invariant is therefore
9
+ * unit-testable without any model in the loop.
10
+ */
11
+ import { TaskContractSchema, TierSchema } from '@kernloop/contracts';
12
+ import { z } from 'zod';
13
+ import { BudgetExceededError, InvalidParentError, InvalidSubtaskError } from './errors.js';
14
+ import { SHIPPED_TEMPLATE_NAMES } from './templates.js';
15
+ /** Authority ladder, lowest first (spec §3.2). */
16
+ const TIER_ORDER = TierSchema.options;
17
+ /** The lower of two tiers on the ladder. */
18
+ function minTier(a, b) {
19
+ return TIER_ORDER.indexOf(a) <= TIER_ORDER.indexOf(b) ? a : b;
20
+ }
21
+ /**
22
+ * A child budget as the PM proposes it. Stricter than TaskContract's
23
+ * nonnegative budget: a zero or negative slice on any dimension is rejected
24
+ * — a child with nothing to spend is a stub, and stubs are forbidden.
25
+ */
26
+ const SubtaskBudgetSchema = z.strictObject({
27
+ tokens: z.number().int().positive(),
28
+ usd: z.number().positive(),
29
+ wallClockMin: z.number().positive(),
30
+ });
31
+ /**
32
+ * One subtask as proposed by the PM. Identity, overlay, and authority are
33
+ * NOT inputs — they are derived from the parent here, so a PM cannot grant
34
+ * what the parent does not hold.
35
+ */
36
+ export const SubtaskSpecSchema = z.strictObject({
37
+ goal: z.string().min(1),
38
+ constraints: z.array(z.string().min(1)).optional(),
39
+ budget: SubtaskBudgetSchema,
40
+ evidence: TaskContractSchema.shape.evidence.optional(),
41
+ definitionOfDone: TaskContractSchema.shape.definitionOfDone.optional(),
42
+ /** Shipped template name this child is assigned to (custom templates: P3, #177). */
43
+ assignTo: z.enum(SHIPPED_TEMPLATE_NAMES),
44
+ });
45
+ /** Parse one subtask spec, wrapping any schema failure as a typed error. */
46
+ function parseSubtask(spec, index) {
47
+ const parsed = SubtaskSpecSchema.safeParse(spec);
48
+ if (!parsed.success) {
49
+ throw new InvalidSubtaskError(index, z.prettifyError(parsed.error));
50
+ }
51
+ return parsed.data;
52
+ }
53
+ /** Enforce sum(child) ≤ parent independently per budget dimension. */
54
+ function checkBudgetInvariant(parent, subtasks) {
55
+ for (const dimension of ['tokens', 'usd', 'wallClockMin']) {
56
+ const childSum = subtasks.reduce((sum, s) => sum + s.budget[dimension], 0);
57
+ if (childSum > parent.budget[dimension]) {
58
+ throw new BudgetExceededError(dimension, parent.budget[dimension], childSum);
59
+ }
60
+ }
61
+ }
62
+ /**
63
+ * Derive zod-valid child TaskContracts from a parent plus PM-proposed
64
+ * subtask specs, enforcing (CLM-0041):
65
+ *
66
+ * - BUDGET INVARIANT: child budgets sum within the parent's on each of
67
+ * tokens, usd, and wallClockMin independently; any breach throws
68
+ * {@link BudgetExceededError} naming the dimension and amounts. An exact
69
+ * sum is within budget. Zero/negative child slices are rejected.
70
+ * - Identity: `child.id = parent.id + '.<n>'` (1-based input order),
71
+ * `child.parent = parent.id`, `child.overlay = parent.overlay`.
72
+ * - Authority: `child.authorityCeiling = min(parent ceiling, 'suggest')`.
73
+ * Children NEVER exceed the parent ceiling, and agent work is generative,
74
+ * so it is additionally clamped at the `suggest` entry tier (spec §3.2);
75
+ * the spec is silent on per-child explicit ceilings, so none is accepted
76
+ * — a PM cannot grant authority (narrowest reading, recorded).
77
+ * - Constraints: parent constraints bind children, so each child inherits
78
+ * them, followed by the subtask's own constraints, followed by a routing
79
+ * constraint `assign:agent.<template>` naming the assigned template's
80
+ * capability.
81
+ *
82
+ * Fan-out parallelism is bounded by the parent budget as a consequence: the
83
+ * kernel meters, the PM allocates (spec §5.4).
84
+ */
85
+ export function decomposePlan(input) {
86
+ const parentResult = TaskContractSchema.safeParse(input.parent);
87
+ if (!parentResult.success) {
88
+ throw new InvalidParentError(z.prettifyError(parentResult.error));
89
+ }
90
+ const parent = parentResult.data;
91
+ const subtasks = input.subtasks.map((spec, i) => parseSubtask(spec, i));
92
+ checkBudgetInvariant(parent, subtasks);
93
+ return subtasks.map((spec, i) => TaskContractSchema.parse({
94
+ id: `${parent.id}.${i + 1}`,
95
+ parent: parent.id,
96
+ goal: spec.goal,
97
+ constraints: [
98
+ ...parent.constraints,
99
+ ...(spec.constraints ?? []),
100
+ `assign:agent.${spec.assignTo}`,
101
+ ],
102
+ budget: spec.budget,
103
+ evidence: spec.evidence ?? [],
104
+ definitionOfDone: spec.definitionOfDone ?? [],
105
+ authorityCeiling: minTier(parent.authorityCeiling, 'suggest'),
106
+ overlay: parent.overlay,
107
+ }));
108
+ }
109
+ //# sourceMappingURL=decompose.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decompose.js","sourceRoot":"","sources":["../src/decompose.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Typed errors thrown at the workforce faculty's boundaries. Callers
3
+ * discriminate on `name` or `instanceof` — never on message text.
4
+ */
5
+ import type { TaskContract } from '@kernloop/contracts';
6
+ /** The three independently-summed budget dimensions of a TaskContract. */
7
+ export type BudgetDimension = keyof TaskContract['budget'];
8
+ /**
9
+ * Thrown when the sum of child budgets exceeds the parent budget on any
10
+ * dimension (spec §5.4: child TaskContract budgets "must sum within the
11
+ * parent's"; CLM-0041). Carries the offending dimension and both amounts so
12
+ * the caller can report — or a PM can replan — without parsing text.
13
+ */
14
+ export declare class BudgetExceededError extends Error {
15
+ readonly dimension: BudgetDimension;
16
+ readonly parentBudget: number;
17
+ readonly childSum: number;
18
+ constructor(dimension: BudgetDimension, parentBudget: number, childSum: number);
19
+ }
20
+ /**
21
+ * Thrown when a subtask spec is malformed for a reason other than the
22
+ * budget-sum invariant: schema violation, zero/negative budget dimension,
23
+ * or `assignTo` naming no shipped template.
24
+ */
25
+ export declare class InvalidSubtaskError extends Error {
26
+ /** Zero-based index of the offending subtask in the input array. */
27
+ readonly index: number;
28
+ constructor(index: number, message: string);
29
+ }
30
+ /**
31
+ * Thrown when the parent contract handed to decomposePlan fails
32
+ * TaskContractSchema validation (charter: zod-validate at every contract
33
+ * boundary).
34
+ */
35
+ export declare class InvalidParentError extends Error {
36
+ constructor(message: string);
37
+ }
38
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,0EAA0E;AAC1E,MAAM,MAAM,eAAe,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;AAE3D;;;;;GAKG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAU/E;AAED;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,oEAAoE;IACpE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAEX,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAK3C;AAED;;;;GAIG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B"}
package/dist/errors.js ADDED
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Thrown when the sum of child budgets exceeds the parent budget on any
3
+ * dimension (spec §5.4: child TaskContract budgets "must sum within the
4
+ * parent's"; CLM-0041). Carries the offending dimension and both amounts so
5
+ * the caller can report — or a PM can replan — without parsing text.
6
+ */
7
+ export class BudgetExceededError extends Error {
8
+ dimension;
9
+ parentBudget;
10
+ childSum;
11
+ constructor(dimension, parentBudget, childSum) {
12
+ super(`child budgets exceed parent on ${dimension}: ` +
13
+ `sum ${childSum} > parent ${parentBudget} (spec §5.4)`);
14
+ this.name = 'BudgetExceededError';
15
+ this.dimension = dimension;
16
+ this.parentBudget = parentBudget;
17
+ this.childSum = childSum;
18
+ }
19
+ }
20
+ /**
21
+ * Thrown when a subtask spec is malformed for a reason other than the
22
+ * budget-sum invariant: schema violation, zero/negative budget dimension,
23
+ * or `assignTo` naming no shipped template.
24
+ */
25
+ export class InvalidSubtaskError extends Error {
26
+ /** Zero-based index of the offending subtask in the input array. */
27
+ index;
28
+ constructor(index, message) {
29
+ super(`subtask[${index}]: ${message}`);
30
+ this.name = 'InvalidSubtaskError';
31
+ this.index = index;
32
+ }
33
+ }
34
+ /**
35
+ * Thrown when the parent contract handed to decomposePlan fails
36
+ * TaskContractSchema validation (charter: zod-validate at every contract
37
+ * boundary).
38
+ */
39
+ export class InvalidParentError extends Error {
40
+ constructor(message) {
41
+ super(message);
42
+ this.name = 'InvalidParentError';
43
+ }
44
+ }
45
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AASA;;;;;GAKG;AACH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IACnC,SAAS,CAAkB;IAC3B,YAAY,CAAS;IACrB,QAAQ,CAAS;IAE1B,YAAY,SAA0B,EAAE,YAAoB,EAAE,QAAgB;QAC5E,KAAK,CACH,kCAAkC,SAAS,IAAI;YAC7C,OAAO,QAAQ,aAAa,YAAY,cAAc,CACzD,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C,oEAAoE;IAC3D,KAAK,CAAS;IAEvB,YAAY,KAAa,EAAE,OAAe;QACxC,KAAK,CAAC,WAAW,KAAK,MAAM,OAAO,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @kernloop/faculty-workforce — Layer 2 workforce faculty (spec §5.4).
3
+ *
4
+ * Agents are configuration, not generation: five shipped templates (PM,
5
+ * Coder, Reviewer, Documenter, Researcher) instantiate as agentTemplate
6
+ * Manifests (CLM-0040), and PM plan decomposition is mechanically enforced
7
+ * under the budget-sum invariant (CLM-0041). This package contains no model
8
+ * calls — generative work happens through an invoke function injected by
9
+ * the composition root. It imports only @kernloop/contracts and external
10
+ * dependencies (constitutional rule 5).
11
+ */
12
+ export { AgentTemplateSchema, MODEL_TIER_COST, SHIPPED_TEMPLATES, SHIPPED_TEMPLATE_NAMES, } from './templates.js';
13
+ export type { AgentTemplate, ShippedTemplateName } from './templates.js';
14
+ export { instantiateAgent, InstantiateOptionsSchema, WORKFORCE_VERSION } from './instantiate.js';
15
+ export type { InstantiateOptions } from './instantiate.js';
16
+ export { decomposePlan, SubtaskSpecSchema } from './decompose.js';
17
+ export type { SubtaskSpec, DecomposePlanInput } from './decompose.js';
18
+ export { BudgetExceededError, InvalidParentError, InvalidSubtaskError } from './errors.js';
19
+ export type { BudgetDimension } from './errors.js';
20
+ export { workforceManifest } from './manifest.js';
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACjG,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAClE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC3F,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @kernloop/faculty-workforce — Layer 2 workforce faculty (spec §5.4).
3
+ *
4
+ * Agents are configuration, not generation: five shipped templates (PM,
5
+ * Coder, Reviewer, Documenter, Researcher) instantiate as agentTemplate
6
+ * Manifests (CLM-0040), and PM plan decomposition is mechanically enforced
7
+ * under the budget-sum invariant (CLM-0041). This package contains no model
8
+ * calls — generative work happens through an invoke function injected by
9
+ * the composition root. It imports only @kernloop/contracts and external
10
+ * dependencies (constitutional rule 5).
11
+ */
12
+ export { AgentTemplateSchema, MODEL_TIER_COST, SHIPPED_TEMPLATES, SHIPPED_TEMPLATE_NAMES, } from './templates.js';
13
+ export { instantiateAgent, InstantiateOptionsSchema, WORKFORCE_VERSION } from './instantiate.js';
14
+ export { decomposePlan, SubtaskSpecSchema } from './decompose.js';
15
+ export { BudgetExceededError, InvalidParentError, InvalidSubtaskError } from './errors.js';
16
+ export { workforceManifest } from './manifest.js';
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEjG,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAElE,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAE3F,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Template → Manifest instantiation (spec §5.4; CLM-0040). Purely
3
+ * mechanical: validate the template, stamp it into a `agentTemplate`
4
+ * Manifest, and parse the result through ManifestSchema so an invalid
5
+ * instantiation fails fast.
6
+ */
7
+ import { type Manifest } from '@kernloop/contracts';
8
+ import { z } from 'zod';
9
+ import { type AgentTemplate } from './templates.js';
10
+ /** Version stamped on every instantiated agent manifest. */
11
+ export declare const WORKFORCE_VERSION = "0.1.0";
12
+ /** Options for {@link instantiateAgent}. */
13
+ export declare const InstantiateOptionsSchema: z.ZodObject<{
14
+ overlay: z.ZodString;
15
+ overrides: z.ZodOptional<z.ZodObject<{
16
+ name: z.ZodOptional<z.ZodString>;
17
+ rolePrompt: z.ZodOptional<z.ZodString>;
18
+ skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
19
+ model: z.ZodOptional<z.ZodObject<{
20
+ tier: z.ZodDefault<z.ZodEnum<{
21
+ frontier: "frontier";
22
+ large: "large";
23
+ medium: "medium";
24
+ small: "small";
25
+ }>>;
26
+ effort: z.ZodDefault<z.ZodEnum<{
27
+ medium: "medium";
28
+ low: "low";
29
+ high: "high";
30
+ xhigh: "xhigh";
31
+ }>>;
32
+ capabilities: z.ZodDefault<z.ZodArray<z.ZodEnum<{
33
+ toolUse: "toolUse";
34
+ vision: "vision";
35
+ longContext: "longContext";
36
+ jsonMode: "jsonMode";
37
+ }>>>;
38
+ }, z.core.$strict>>;
39
+ budgetShare: z.ZodOptional<z.ZodNumber>;
40
+ }, z.core.$strict>>;
41
+ }, z.core.$strict>;
42
+ export type InstantiateOptions = z.infer<typeof InstantiateOptionsSchema>;
43
+ /**
44
+ * Instantiate an agent template as a Manifest (kind `agentTemplate`).
45
+ *
46
+ * - `tier` is always `suggest`: templates are generative components and
47
+ * anything generative enters at `suggest` (spec §3.2, §5.4); promotion is
48
+ * never a default.
49
+ * - `maturity` is `stable` only for an unmodified shipped template (PM,
50
+ * Coder, Reviewer, Documenter, Researcher); any custom template — composed
51
+ * from existing ones via `overrides` or supplied whole — is
52
+ * `experimental` until ratified into the library.
53
+ * - `claims` is empty: an instantiated agent is a runtime configuration
54
+ * record, not a repo capability; the claim backing this machinery
55
+ * (CLM-0040) lives on the faculty manifest.
56
+ * - the model `tier`/`effort` and `overlay` are recorded in the capability
57
+ * description; the cost profile reflects the tier and the `model`
58
+ * requirement is stamped onto the manifest (spec §8.4). Binding the tier to
59
+ * a concrete model id is the composition root's concern.
60
+ *
61
+ * DEFERRED (P3, #178): the spec grants the PM authority to compose bespoke
62
+ * specialists at `enforce`. Per the P2 design-notes ratification point, that
63
+ * enforce grant is deferred to P3 evidence — there is deliberately no
64
+ * enforce path here, and composed templates come out `suggest`/
65
+ * `experimental` like any other custom template.
66
+ */
67
+ export declare function instantiateAgent(template: AgentTemplate, options: InstantiateOptions): Manifest;
68
+ //# sourceMappingURL=instantiate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instantiate.d.ts","sourceRoot":"","sources":["../src/instantiate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,gBAAgB,CAAC;AAExB,4DAA4D;AAC5D,eAAO,MAAM,iBAAiB,UAAU,CAAC;AAEzC,4CAA4C;AAC5C,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAUnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAQ1E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,kBAAkB,GAAG,QAAQ,CA6B/F"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Template → Manifest instantiation (spec §5.4; CLM-0040). Purely
3
+ * mechanical: validate the template, stamp it into a `agentTemplate`
4
+ * Manifest, and parse the result through ManifestSchema so an invalid
5
+ * instantiation fails fast.
6
+ */
7
+ import { ManifestSchema } from '@kernloop/contracts';
8
+ import { z } from 'zod';
9
+ import { AgentTemplateSchema, MODEL_TIER_COST, SHIPPED_TEMPLATES, } from './templates.js';
10
+ /** Version stamped on every instantiated agent manifest. */
11
+ export const WORKFORCE_VERSION = '0.1.0';
12
+ /** Options for {@link instantiateAgent}. */
13
+ export const InstantiateOptionsSchema = z.strictObject({
14
+ /** Repo overlay id the agent serves (spec §7); recorded in the capability description. */
15
+ overlay: z.string().min(1),
16
+ /**
17
+ * Field overrides composing a CUSTOM template from an existing one. Any
18
+ * override — even an identity rewrite — makes the result custom:
19
+ * `experimental` maturity at `suggest` tier, ratified into the library
20
+ * later (spec §5.4).
21
+ */
22
+ overrides: AgentTemplateSchema.partial().optional(),
23
+ });
24
+ /** True iff `t` is byte-for-byte one of the five shipped templates. */
25
+ function isShipped(t) {
26
+ const shipped = SHIPPED_TEMPLATES[t.name];
27
+ return shipped !== undefined && JSON.stringify(shipped) === JSON.stringify(t);
28
+ }
29
+ /**
30
+ * Instantiate an agent template as a Manifest (kind `agentTemplate`).
31
+ *
32
+ * - `tier` is always `suggest`: templates are generative components and
33
+ * anything generative enters at `suggest` (spec §3.2, §5.4); promotion is
34
+ * never a default.
35
+ * - `maturity` is `stable` only for an unmodified shipped template (PM,
36
+ * Coder, Reviewer, Documenter, Researcher); any custom template — composed
37
+ * from existing ones via `overrides` or supplied whole — is
38
+ * `experimental` until ratified into the library.
39
+ * - `claims` is empty: an instantiated agent is a runtime configuration
40
+ * record, not a repo capability; the claim backing this machinery
41
+ * (CLM-0040) lives on the faculty manifest.
42
+ * - the model `tier`/`effort` and `overlay` are recorded in the capability
43
+ * description; the cost profile reflects the tier and the `model`
44
+ * requirement is stamped onto the manifest (spec §8.4). Binding the tier to
45
+ * a concrete model id is the composition root's concern.
46
+ *
47
+ * DEFERRED (P3, #178): the spec grants the PM authority to compose bespoke
48
+ * specialists at `enforce`. Per the P2 design-notes ratification point, that
49
+ * enforce grant is deferred to P3 evidence — there is deliberately no
50
+ * enforce path here, and composed templates come out `suggest`/
51
+ * `experimental` like any other custom template.
52
+ */
53
+ export function instantiateAgent(template, options) {
54
+ const opts = InstantiateOptionsSchema.parse(options);
55
+ const base = AgentTemplateSchema.parse(template);
56
+ const effective = opts.overrides === undefined ? base : AgentTemplateSchema.parse({ ...base, ...opts.overrides });
57
+ const custom = opts.overrides !== undefined || !isShipped(effective);
58
+ return ManifestSchema.parse({
59
+ name: `workforce/${effective.name}`,
60
+ version: WORKFORCE_VERSION,
61
+ kind: 'agentTemplate',
62
+ capabilities: [
63
+ {
64
+ name: `agent.${effective.name}`,
65
+ description: `${effective.name} agent (${effective.model.tier} tier, ${effective.model.effort} effort, ` +
66
+ `budget share ${effective.budgetShare}, skills: ${effective.skills.join(', ') || 'none'}) ` +
67
+ `for overlay ${opts.overlay}`,
68
+ },
69
+ ],
70
+ contracts: {
71
+ consumes: ['TaskContract'],
72
+ emits: ['Outcome'],
73
+ },
74
+ cost: MODEL_TIER_COST[effective.model.tier],
75
+ tier: 'suggest',
76
+ claims: [],
77
+ maturity: custom ? 'experimental' : 'stable',
78
+ model: effective.model,
79
+ });
80
+ }
81
+ //# sourceMappingURL=instantiate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instantiate.js","sourceRoot":"","sources":["../src/instantiate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,cAAc,EAAiB,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,iBAAiB,GAElB,MAAM,gBAAgB,CAAC;AAExB,4DAA4D;AAC5D,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAEzC,4CAA4C;AAC5C,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,YAAY,CAAC;IACrD,0FAA0F;IAC1F,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B;;;;;OAKG;IACH,SAAS,EAAE,mBAAmB,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACpD,CAAC,CAAC;AAGH,uEAAuE;AACvE,SAAS,SAAS,CAAC,CAAgB;IACjC,MAAM,OAAO,GAAG,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAuB,EAAE,OAA2B;IACnF,MAAM,IAAI,GAAG,wBAAwB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACrD,MAAM,IAAI,GAAG,mBAAmB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACjD,MAAM,SAAS,GACb,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAClG,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACrE,OAAO,cAAc,CAAC,KAAK,CAAC;QAC1B,IAAI,EAAE,aAAa,SAAS,CAAC,IAAI,EAAE;QACnC,OAAO,EAAE,iBAAiB;QAC1B,IAAI,EAAE,eAAe;QACrB,YAAY,EAAE;YACZ;gBACE,IAAI,EAAE,SAAS,SAAS,CAAC,IAAI,EAAE;gBAC/B,WAAW,EACT,GAAG,SAAS,CAAC,IAAI,WAAW,SAAS,CAAC,KAAK,CAAC,IAAI,UAAU,SAAS,CAAC,KAAK,CAAC,MAAM,WAAW;oBAC3F,gBAAgB,SAAS,CAAC,WAAW,aAAa,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,IAAI;oBAC3F,eAAe,IAAI,CAAC,OAAO,EAAE;aAChC;SACF;QACD,SAAS,EAAE;YACT,QAAQ,EAAE,CAAC,cAAc,CAAC;YAC1B,KAAK,EAAE,CAAC,SAAS,CAAC;SACnB;QACD,IAAI,EAAE,eAAe,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC;QAC3C,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ;QAC5C,KAAK,EAAE,SAAS,CAAC,KAAK;KACvB,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The workforce faculty's registration record (spec §4, §5.4). Parsed
3
+ * through `ManifestSchema` at module load so an invalid manifest fails
4
+ * fast, not at registry time.
5
+ */
6
+ import { type Manifest } from '@kernloop/contracts';
7
+ /**
8
+ * The faculty-workforce registration manifest. Tier is `suggest` — the
9
+ * workforce stands behind the PM, a generative role, and anything
10
+ * generative enters at `suggest` (spec §3.2); promotion needs evidence +
11
+ * ratification. Consumes TaskContract (the parent plan) and emits
12
+ * TaskContract (the derived children). Cost is zero tokens/usd: template
13
+ * instantiation and decomposition enforcement are mechanical — the PM's
14
+ * generative work runs through the composition-root-injected invoke, where
15
+ * the adapters meter it.
16
+ */
17
+ export declare const workforceManifest: Manifest;
18
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpE;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,EAAE,QA0B9B,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * The workforce faculty's registration record (spec §4, §5.4). Parsed
3
+ * through `ManifestSchema` at module load so an invalid manifest fails
4
+ * fast, not at registry time.
5
+ */
6
+ import { ManifestSchema } from '@kernloop/contracts';
7
+ /**
8
+ * The faculty-workforce registration manifest. Tier is `suggest` — the
9
+ * workforce stands behind the PM, a generative role, and anything
10
+ * generative enters at `suggest` (spec §3.2); promotion needs evidence +
11
+ * ratification. Consumes TaskContract (the parent plan) and emits
12
+ * TaskContract (the derived children). Cost is zero tokens/usd: template
13
+ * instantiation and decomposition enforcement are mechanical — the PM's
14
+ * generative work runs through the composition-root-injected invoke, where
15
+ * the adapters meter it.
16
+ */
17
+ export const workforceManifest = ManifestSchema.parse({
18
+ name: '@kernloop/faculty-workforce',
19
+ version: '0.1.0',
20
+ kind: 'faculty',
21
+ capabilities: [
22
+ {
23
+ name: 'workforce.instantiate',
24
+ description: 'Instantiate an agent template as an agentTemplate Manifest (spec §5.4)',
25
+ },
26
+ {
27
+ name: 'workforce.decompose',
28
+ description: 'Derive child TaskContracts from a parent plan under the budget-sum invariant',
29
+ },
30
+ ],
31
+ contracts: {
32
+ consumes: ['TaskContract'],
33
+ emits: ['TaskContract'],
34
+ },
35
+ cost: {
36
+ tokens: 0,
37
+ usd: 0,
38
+ latencyMs: 10,
39
+ },
40
+ tier: 'suggest',
41
+ claims: ['CLM-0040', 'CLM-0041'],
42
+ maturity: 'stable',
43
+ });
44
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,cAAc,EAAiB,MAAM,qBAAqB,CAAC;AAEpE;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAa,cAAc,CAAC,KAAK,CAAC;IAC9D,IAAI,EAAE,6BAA6B;IACnC,OAAO,EAAE,OAAO;IAChB,IAAI,EAAE,SAAS;IACf,YAAY,EAAE;QACZ;YACE,IAAI,EAAE,uBAAuB;YAC7B,WAAW,EAAE,wEAAwE;SACtF;QACD;YACE,IAAI,EAAE,qBAAqB;YAC3B,WAAW,EAAE,8EAA8E;SAC5F;KACF;IACD,SAAS,EAAE;QACT,QAAQ,EAAE,CAAC,cAAc,CAAC;QAC1B,KAAK,EAAE,CAAC,cAAc,CAAC;KACxB;IACD,IAAI,EAAE;QACJ,MAAM,EAAE,CAAC;QACT,GAAG,EAAE,CAAC;QACN,SAAS,EAAE,EAAE;KACd;IACD,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,EAAE,QAAQ;CACnB,CAAC,CAAC"}
@@ -0,0 +1,92 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * One workforce agent template (spec §5.4): role prompt + skill set + model
4
+ * requirement + budget slice. `budgetShare` is the fraction of the parent
5
+ * task's budget this role may receive by default when the PM slices budgets —
6
+ * a default allocation hint, not a kernel-enforced ceiling (the kernel
7
+ * meters, the PM allocates).
8
+ *
9
+ * `model` is the role's two-axis {@link ModelRequirement} (spec §8.4): the
10
+ * model `tier` (frontier > large > medium > small) and reasoning `effort` the
11
+ * role demands. Mapping a tier+effort to a concrete model id + effort arg is a
12
+ * composition-root concern resolved through the kernel translation seam; this
13
+ * faculty only declares the requirement as configuration.
14
+ */
15
+ export declare const AgentTemplateSchema: z.ZodObject<{
16
+ name: z.ZodString;
17
+ rolePrompt: z.ZodString;
18
+ skills: z.ZodArray<z.ZodString>;
19
+ model: z.ZodObject<{
20
+ tier: z.ZodDefault<z.ZodEnum<{
21
+ frontier: "frontier";
22
+ large: "large";
23
+ medium: "medium";
24
+ small: "small";
25
+ }>>;
26
+ effort: z.ZodDefault<z.ZodEnum<{
27
+ medium: "medium";
28
+ low: "low";
29
+ high: "high";
30
+ xhigh: "xhigh";
31
+ }>>;
32
+ capabilities: z.ZodDefault<z.ZodArray<z.ZodEnum<{
33
+ toolUse: "toolUse";
34
+ vision: "vision";
35
+ longContext: "longContext";
36
+ jsonMode: "jsonMode";
37
+ }>>>;
38
+ }, z.core.$strict>;
39
+ budgetShare: z.ZodNumber;
40
+ }, z.core.$strict>;
41
+ export type AgentTemplate = z.infer<typeof AgentTemplateSchema>;
42
+ /**
43
+ * Expected cost profile per model tier, declared on instantiated manifests
44
+ * for router budget-matching (spec §3.1). Expectations, not meters — the
45
+ * kernel adapters meter actual spend per call. Effort is noted, not separately
46
+ * priced: a tier's row is the expectation at its default effort; raising
47
+ * effort raises realized tokens, which the per-call meters capture.
48
+ */
49
+ export declare const MODEL_TIER_COST: {
50
+ readonly frontier: {
51
+ readonly tokens: 48000;
52
+ readonly usd: 0.8;
53
+ readonly latencyMs: 180000;
54
+ };
55
+ readonly large: {
56
+ readonly tokens: 32000;
57
+ readonly usd: 0.5;
58
+ readonly latencyMs: 120000;
59
+ };
60
+ readonly medium: {
61
+ readonly tokens: 16000;
62
+ readonly usd: 0.1;
63
+ readonly latencyMs: 60000;
64
+ };
65
+ readonly small: {
66
+ readonly tokens: 8000;
67
+ readonly usd: 0.02;
68
+ readonly latencyMs: 30000;
69
+ };
70
+ };
71
+ /**
72
+ * The five shipped templates (spec §5.4): PM, Coder, Reviewer, Documenter,
73
+ * Researcher. Research ships as a single Researcher template + the
74
+ * `research` skill pack — NOT a faculty (spec §5.8). Shipped templates are
75
+ * `stable`; anything else instantiates as `experimental` (see
76
+ * instantiateAgent). Tiers reflect each role's load (spec §8.4): the
77
+ * load-bearing generation roles (Coder, PM, Researcher) on `large` at high
78
+ * effort; the judging/writing roles (Reviewer, Documenter) on `medium`.
79
+ *
80
+ * ROUTING (honesty, #45/#200): in the canonical loop today only PM, Coder, and
81
+ * Researcher are routed (to the plan/decompose, implement, and research nodes),
82
+ * and child review runs as a separate advisory GATE (faculty-gates/review), NOT
83
+ * this Reviewer template. The Reviewer/Documenter templates are shipped
84
+ * specialists the runtime loop does NOT yet route to — a child's `assignTo`
85
+ * records the intended specialist as provenance, but every fan-out child is
86
+ * currently implemented by the Coder until specialist routing lands (#200).
87
+ */
88
+ export declare const SHIPPED_TEMPLATES: Readonly<Record<string, AgentTemplate>>;
89
+ /** Names of the five shipped templates, in spec §5.4 order. */
90
+ export declare const SHIPPED_TEMPLATE_NAMES: readonly ["pm", "coder", "reviewer", "documenter", "researcher"];
91
+ export type ShippedTemplateName = (typeof SHIPPED_TEMPLATE_NAMES)[number];
92
+ //# sourceMappingURL=templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;kBAW9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE;;;;;;GAMG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;CAK8D,CAAC;AAQ3F;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAoDrE,CAAC;AAEF,+DAA+D;AAC/D,eAAO,MAAM,sBAAsB,kEAMzB,CAAC;AACX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Agent templates as DATA (spec §5.4: "configuration, not generation").
3
+ * An agent is a manifest instantiated from a template: role prompt + skill
4
+ * set + model requirement + budget slice. Nothing here calls a model —
5
+ * generative work happens through an invoke function the composition root
6
+ * binds to the kernel adapters later.
7
+ */
8
+ import { ModelRequirementSchema } from '@kernloop/contracts';
9
+ import { z } from 'zod';
10
+ /**
11
+ * One workforce agent template (spec §5.4): role prompt + skill set + model
12
+ * requirement + budget slice. `budgetShare` is the fraction of the parent
13
+ * task's budget this role may receive by default when the PM slices budgets —
14
+ * a default allocation hint, not a kernel-enforced ceiling (the kernel
15
+ * meters, the PM allocates).
16
+ *
17
+ * `model` is the role's two-axis {@link ModelRequirement} (spec §8.4): the
18
+ * model `tier` (frontier > large > medium > small) and reasoning `effort` the
19
+ * role demands. Mapping a tier+effort to a concrete model id + effort arg is a
20
+ * composition-root concern resolved through the kernel translation seam; this
21
+ * faculty only declares the requirement as configuration.
22
+ */
23
+ export const AgentTemplateSchema = z.strictObject({
24
+ /** Stable template name, e.g. `pm`; becomes `workforce/<name>` on instantiation. */
25
+ name: z.string().regex(/^[a-z][a-z0-9-]*$/, 'template name must be lowercase kebab-case'),
26
+ /** The role prompt the agent runs under. */
27
+ rolePrompt: z.string().min(1),
28
+ /** Skill names from the skill library this role loads (spec §5.2 procedural memory). */
29
+ skills: z.array(z.string().min(1)),
30
+ /** The role's two-axis model demand (spec §8.4): tier + effort + capabilities. */
31
+ model: ModelRequirementSchema,
32
+ /** Default fraction (0, 1] of the parent budget this role may receive. */
33
+ budgetShare: z.number().gt(0).max(1),
34
+ });
35
+ /**
36
+ * Expected cost profile per model tier, declared on instantiated manifests
37
+ * for router budget-matching (spec §3.1). Expectations, not meters — the
38
+ * kernel adapters meter actual spend per call. Effort is noted, not separately
39
+ * priced: a tier's row is the expectation at its default effort; raising
40
+ * effort raises realized tokens, which the per-call meters capture.
41
+ */
42
+ export const MODEL_TIER_COST = {
43
+ frontier: { tokens: 48_000, usd: 0.8, latencyMs: 180_000 },
44
+ large: { tokens: 32_000, usd: 0.5, latencyMs: 120_000 },
45
+ medium: { tokens: 16_000, usd: 0.1, latencyMs: 60_000 },
46
+ small: { tokens: 8_000, usd: 0.02, latencyMs: 30_000 },
47
+ };
48
+ /** Build a {@link ModelRequirement} from a partial, applying the schema defaults. */
49
+ const model = (req) => ModelRequirementSchema.parse(req);
50
+ const template = (t) => AgentTemplateSchema.parse(t);
51
+ /**
52
+ * The five shipped templates (spec §5.4): PM, Coder, Reviewer, Documenter,
53
+ * Researcher. Research ships as a single Researcher template + the
54
+ * `research` skill pack — NOT a faculty (spec §5.8). Shipped templates are
55
+ * `stable`; anything else instantiates as `experimental` (see
56
+ * instantiateAgent). Tiers reflect each role's load (spec §8.4): the
57
+ * load-bearing generation roles (Coder, PM, Researcher) on `large` at high
58
+ * effort; the judging/writing roles (Reviewer, Documenter) on `medium`.
59
+ *
60
+ * ROUTING (honesty, #45/#200): in the canonical loop today only PM, Coder, and
61
+ * Researcher are routed (to the plan/decompose, implement, and research nodes),
62
+ * and child review runs as a separate advisory GATE (faculty-gates/review), NOT
63
+ * this Reviewer template. The Reviewer/Documenter templates are shipped
64
+ * specialists the runtime loop does NOT yet route to — a child's `assignTo`
65
+ * records the intended specialist as provenance, but every fan-out child is
66
+ * currently implemented by the Coder until specialist routing lands (#200).
67
+ */
68
+ export const SHIPPED_TEMPLATES = {
69
+ pm: template({
70
+ name: 'pm',
71
+ rolePrompt: 'You are the PM. Decompose the ratified plan into child TaskContracts, ' +
72
+ 'each with a goal, evidence requirements, a definition of done, and a ' +
73
+ 'budget slice. Child budgets must sum within the parent budget on every ' +
74
+ 'dimension; the kernel meters, you allocate.',
75
+ skills: ['plan-decomposition', 'budget-allocation'],
76
+ model: model({ tier: 'large', effort: 'high' }),
77
+ budgetShare: 0.1,
78
+ }),
79
+ coder: template({
80
+ name: 'coder',
81
+ rolePrompt: 'You are the Coder. Implement exactly the child TaskContract you were ' +
82
+ 'assigned: satisfy its definition of done, produce its evidence, and ' +
83
+ 'respect its constraints and budget. Wiring-complete or absent.',
84
+ skills: ['implementation', 'testing'],
85
+ model: model({ tier: 'large', effort: 'high' }),
86
+ budgetShare: 0.5,
87
+ }),
88
+ reviewer: template({
89
+ name: 'reviewer',
90
+ rolePrompt: 'You are the Reviewer. Adversarially review the proposed change against ' +
91
+ 'its contract: correctness, constraint violations, untested claims. ' +
92
+ 'Report severity-tagged findings; do not rewrite the work.',
93
+ skills: ['diff-review'],
94
+ model: model({ tier: 'medium', effort: 'high' }),
95
+ budgetShare: 0.15,
96
+ }),
97
+ documenter: template({
98
+ name: 'documenter',
99
+ rolePrompt: 'You are the Documenter. Update docs in the same change set, tagging ' +
100
+ 'every capability statement with its claim id. Documentation may state ' +
101
+ 'only verified capability.',
102
+ skills: ['docs'],
103
+ model: model({ tier: 'medium', effort: 'high' }),
104
+ budgetShare: 0.1,
105
+ }),
106
+ researcher: template({
107
+ name: 'researcher',
108
+ rolePrompt: 'You are the Researcher. Gather and condense the source material the ' +
109
+ 'task needs — code, specs, prior art — with provenance on every finding. ' +
110
+ 'You produce inputs for others; you do not implement.',
111
+ skills: ['research'],
112
+ model: model({ tier: 'large', effort: 'high' }),
113
+ budgetShare: 0.15,
114
+ }),
115
+ };
116
+ /** Names of the five shipped templates, in spec §5.4 order. */
117
+ export const SHIPPED_TEMPLATE_NAMES = [
118
+ 'pm',
119
+ 'coder',
120
+ 'reviewer',
121
+ 'documenter',
122
+ 'researcher',
123
+ ];
124
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@kernloop/faculty-workforce",
3
+ "version": "0.1.0",
4
+ "description": "Kernloop Layer 2 — the workforce faculty (spec §5.4). Agents are configuration, not generation: PM, Coder, Reviewer, Documenter, and Researcher templates instantiate as agentTemplate Manifests, and the PM's plan decomposition is mechanically enforced — child TaskContract budgets must sum within the parent's on every dimension. No model calls: generative work happens through an invoke function injected by the composition root.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "dependencies": {
19
+ "zod": "^4.4.3",
20
+ "@kernloop/contracts": "0.1.0"
21
+ },
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/kernloop/kernloop.git",
28
+ "directory": "packages/faculty-workforce"
29
+ },
30
+ "scripts": {
31
+ "build": "tsc -p tsconfig.json",
32
+ "typecheck": "tsc --noEmit -p tsconfig.json",
33
+ "test": "vitest run --coverage"
34
+ }
35
+ }