@dv.nghiem/flowdeck 0.4.12 → 0.5.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/dist/agents/orchestrator.d.ts.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/schema.d.ts +27 -1
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/hooks/approval-hook.d.ts +16 -2
- package/dist/hooks/approval-hook.d.ts.map +1 -1
- package/dist/hooks/compaction-hook.d.ts +1 -1
- package/dist/hooks/compaction-hook.d.ts.map +1 -1
- package/dist/hooks/context-window-monitor.d.ts +7 -1
- package/dist/hooks/context-window-monitor.d.ts.map +1 -1
- package/dist/hooks/decision-trace-hook.d.ts +3 -0
- package/dist/hooks/decision-trace-hook.d.ts.map +1 -1
- package/dist/hooks/event-log-hook.d.ts +19 -3
- package/dist/hooks/event-log-hook.d.ts.map +1 -1
- package/dist/hooks/guard-rails.d.ts +16 -5
- package/dist/hooks/guard-rails.d.ts.map +1 -1
- package/dist/hooks/orchestrator-guard-hook.d.ts +8 -5
- package/dist/hooks/orchestrator-guard-hook.d.ts.map +1 -1
- package/dist/hooks/tool-guard.d.ts +19 -3
- package/dist/hooks/tool-guard.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8367 -4620
- package/dist/services/agent-contract-registry.d.ts.map +1 -1
- package/dist/services/agent-trace-graph.d.ts +4 -0
- package/dist/services/agent-trace-graph.d.ts.map +1 -1
- package/dist/services/agent-validator.d.ts +2 -1
- package/dist/services/agent-validator.d.ts.map +1 -1
- package/dist/services/approval-manager.d.ts +14 -1
- package/dist/services/approval-manager.d.ts.map +1 -1
- package/dist/services/audit-log.d.ts +23 -0
- package/dist/services/audit-log.d.ts.map +1 -0
- package/dist/services/context-ingress.d.ts +75 -0
- package/dist/services/context-ingress.d.ts.map +1 -0
- package/dist/services/deadlock-detector.d.ts.map +1 -1
- package/dist/services/delegation-budget.d.ts +55 -0
- package/dist/services/delegation-budget.d.ts.map +1 -0
- package/dist/services/event-logger.d.ts +3 -1
- package/dist/services/event-logger.d.ts.map +1 -1
- package/dist/services/execution-substrate.d.ts +35 -0
- package/dist/services/execution-substrate.d.ts.map +1 -0
- package/dist/services/harness-controller.d.ts +58 -0
- package/dist/services/harness-controller.d.ts.map +1 -0
- package/dist/services/harness-policy.d.ts +24 -0
- package/dist/services/harness-policy.d.ts.map +1 -0
- package/dist/services/harness-types.d.ts +178 -0
- package/dist/services/harness-types.d.ts.map +1 -0
- package/dist/services/lazy-rule-loader.d.ts +2 -0
- package/dist/services/lazy-rule-loader.d.ts.map +1 -1
- package/dist/services/prompt-cache.d.ts +25 -0
- package/dist/services/prompt-cache.d.ts.map +1 -0
- package/dist/services/recovery-layer.d.ts +26 -0
- package/dist/services/recovery-layer.d.ts.map +1 -0
- package/dist/services/run-trace.d.ts +17 -0
- package/dist/services/run-trace.d.ts.map +1 -1
- package/dist/services/state-persistence.d.ts +22 -0
- package/dist/services/state-persistence.d.ts.map +1 -0
- package/dist/services/supervisor-binding.d.ts +9 -0
- package/dist/services/supervisor-binding.d.ts.map +1 -1
- package/dist/services/token-metrics.d.ts +39 -0
- package/dist/services/token-metrics.d.ts.map +1 -0
- package/dist/services/verification-layer.d.ts +24 -0
- package/dist/services/verification-layer.d.ts.map +1 -0
- package/dist/services/workflow-scorecard.d.ts +5 -0
- package/dist/services/workflow-scorecard.d.ts.map +1 -1
- package/dist/tools/decision-trace.d.ts +4 -0
- package/dist/tools/decision-trace.d.ts.map +1 -1
- package/dist/tools/delegate.d.ts +16 -0
- package/dist/tools/delegate.d.ts.map +1 -0
- package/dist/tools/failure-replay.d.ts +8 -0
- package/dist/tools/failure-replay.d.ts.map +1 -1
- package/dist/tools/policy-engine.d.ts +1 -0
- package/dist/tools/policy-engine.d.ts.map +1 -1
- package/docs/concepts/HARNESS_ARCHITECTURE.md +241 -0
- package/docs/concepts/HARNESS_LAYERS.md +378 -0
- package/docs/concepts/HARNESS_WIRING.md +404 -0
- package/package.json +1 -1
- package/src/commands/fd-guarded-edit.md +69 -0
|
@@ -99,6 +99,8 @@ export declare function detectProjectLanguages(projectRoot: string): string[];
|
|
|
99
99
|
export declare function buildSelectionDiagnostics(selection: RuleSelection, context: SelectionContext): string;
|
|
100
100
|
/** Invalidate the discovery cache (call after rule files change, e.g. in tests). */
|
|
101
101
|
export declare function invalidateRuleCache(): void;
|
|
102
|
+
/** Alias exported for prompt-cache invalidation. */
|
|
103
|
+
export declare function invalidateCache(): void;
|
|
102
104
|
/** Return current cache entry count (for tests/telemetry). */
|
|
103
105
|
export declare function getRuleCacheSize(): number;
|
|
104
106
|
//# sourceMappingURL=lazy-rule-loader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lazy-rule-loader.d.ts","sourceRoot":"","sources":["../../src/services/lazy-rule-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,2DAA2D;AAC3D,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAA;IACnB,oEAAoE;IACpE,SAAS,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB;;;OAGG;IACH,SAAS,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,4CAA4C;AAC5C,MAAM,WAAW,gBAAgB;IAC/B,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,uCAAuC;AACvC,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,YAAY,EAAE,CAAA;IACxB,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAOD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAyBzE;AAkCD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,EAAE,CA0B9D;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,gBAAqB,GAC7B,aAAa,CAiDf;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,iBAAiB,EAAE,MAAM,EAAE,GAC1B,MAAM,EAAE,CAGV;AAID;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAiDpE;AAID;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,gBAAgB,GACxB,MAAM,CAgBR;AAID,oFAAoF;AACpF,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,8DAA8D;AAC9D,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC"}
|
|
1
|
+
{"version":3,"file":"lazy-rule-loader.d.ts","sourceRoot":"","sources":["../../src/services/lazy-rule-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,2DAA2D;AAC3D,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAA;IACnB,oEAAoE;IACpE,SAAS,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB;;;OAGG;IACH,SAAS,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,4CAA4C;AAC5C,MAAM,WAAW,gBAAgB;IAC/B,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,uCAAuC;AACvC,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,YAAY,EAAE,CAAA;IACxB,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAOD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAyBzE;AAkCD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,EAAE,CA0B9D;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,gBAAqB,GAC7B,aAAa,CAiDf;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,iBAAiB,EAAE,MAAM,EAAE,GAC1B,MAAM,EAAE,CAGV;AAID;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAiDpE;AAID;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,gBAAgB,GACxB,MAAM,CAgBR;AAID,oFAAoF;AACpF,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,oDAAoD;AACpD,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAED,8DAA8D;AAC9D,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt Cache
|
|
3
|
+
*
|
|
4
|
+
* Caches assembled prompt fragments keyed by task description, workflow stage,
|
|
5
|
+
* and detected languages. Entries expire after a 5-minute TTL by default.
|
|
6
|
+
*
|
|
7
|
+
* Thread safety: operations are synchronous and run in the single-process event
|
|
8
|
+
* loop, so the internal Map is safe from races.
|
|
9
|
+
*/
|
|
10
|
+
export interface PromptCache {
|
|
11
|
+
/** Build a deterministic cache key from task + stage + languages. */
|
|
12
|
+
getKey(description: string, stage: string, languages: string[]): string;
|
|
13
|
+
/** Return a cached fragment if it is still fresh. */
|
|
14
|
+
get(key: string): string | undefined;
|
|
15
|
+
/** Store a fragment with an optional TTL (defaults to 5 minutes). */
|
|
16
|
+
set(key: string, fragment: string, ttlMs?: number): void;
|
|
17
|
+
/** Drop all cached fragments and invalidate downstream rule caches. */
|
|
18
|
+
invalidate(): void;
|
|
19
|
+
}
|
|
20
|
+
export declare const DEFAULT_PROMPT_CACHE_TTL_MS: number;
|
|
21
|
+
/** Factory for creating a fresh prompt cache (mostly useful in tests). */
|
|
22
|
+
export declare function createPromptCache(): PromptCache;
|
|
23
|
+
/** Shared process-wide prompt cache used by the context ingress service. */
|
|
24
|
+
export declare const sharedPromptCache: PromptCache;
|
|
25
|
+
//# sourceMappingURL=prompt-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-cache.d.ts","sourceRoot":"","sources":["../../src/services/prompt-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,MAAM,WAAW,WAAW;IAC1B,qEAAqE;IACrE,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IACvE,qDAAqD;IACrD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IACpC,qEAAqE;IACrE,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxD,uEAAuE;IACvE,UAAU,IAAI,IAAI,CAAA;CACnB;AAOD,eAAO,MAAM,2BAA2B,QAAgB,CAAA;AAmCxD,0EAA0E;AAC1E,wBAAgB,iBAAiB,IAAI,WAAW,CAE/C;AAED,4EAA4E;AAC5E,eAAO,MAAM,iBAAiB,EAAE,WAAmC,CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recovery Layer
|
|
3
|
+
*
|
|
4
|
+
* Detect stuck runs, explain blockages, recommend recovery actions,
|
|
5
|
+
* surface relevant failures from the failure-replay engine, and bound retries.
|
|
6
|
+
*/
|
|
7
|
+
import { type DeadlockSignal } from "./deadlock-detector";
|
|
8
|
+
import { type FailureEntry } from "../tools/failure-replay";
|
|
9
|
+
import type { RunContext, RecoveryAction } from "./harness-types";
|
|
10
|
+
import type { TaskType } from "./quick-router";
|
|
11
|
+
export interface RecoveryLayer {
|
|
12
|
+
/** Analyze recent spans and signals for stuck patterns. */
|
|
13
|
+
detectStuckRun(dir: string, runId: string): DeadlockSignal[];
|
|
14
|
+
/** Return true if the run has any auto-stop deadlock signal. */
|
|
15
|
+
isRunStuck(dir: string, runId: string): boolean;
|
|
16
|
+
/** Return a human-readable explanation of why the run is blocked. */
|
|
17
|
+
explainBlockage(ctx: RunContext): string;
|
|
18
|
+
/** Recommend the next recovery action: retry, fallback-agent, escalate, stop. */
|
|
19
|
+
recommendRecovery(ctx: RunContext, signals: DeadlockSignal[]): RecoveryAction;
|
|
20
|
+
/** Check whether a retry is still allowed for the current step. */
|
|
21
|
+
canRetry(runId: string): boolean;
|
|
22
|
+
/** Surface recent failures relevant to the current task. */
|
|
23
|
+
getRelevantFailures(dir: string, taskType: TaskType): FailureEntry[];
|
|
24
|
+
}
|
|
25
|
+
export declare function createRecoveryLayer(appLog?: (msg: string) => void): RecoveryLayer;
|
|
26
|
+
//# sourceMappingURL=recovery-layer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-layer.d.ts","sourceRoot":"","sources":["../../src/services/recovery-layer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAGL,KAAK,cAAc,EAEpB,MAAM,qBAAqB,CAAA;AAM5B,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AACjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAE9C,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,EAAE,CAAA;IAC5D,gEAAgE;IAChE,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;IAC/C,qEAAqE;IACrE,eAAe,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAAA;IACxC,iFAAiF;IACjF,iBAAiB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,cAAc,CAAA;IAC7E,mEAAmE;IACnE,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;IAChC,4DAA4D;IAC5D,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,YAAY,EAAE,CAAA;CACrE;AAwCD,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,aAAa,CAoFjF"}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
+
import type { DelegationBudgetSnapshot } from "./delegation-budget";
|
|
1
2
|
export type RunStatus = "running" | "complete" | "failed" | "cancelled";
|
|
3
|
+
export interface VerificationRecord {
|
|
4
|
+
kind: string;
|
|
5
|
+
evidence: string;
|
|
6
|
+
timestamp: string;
|
|
7
|
+
}
|
|
2
8
|
export interface RunTrace {
|
|
3
9
|
run_id: string;
|
|
4
10
|
session_id: string;
|
|
@@ -12,6 +18,8 @@ export interface RunTrace {
|
|
|
12
18
|
risk_score: number;
|
|
13
19
|
outcome?: string;
|
|
14
20
|
error?: string;
|
|
21
|
+
budget_snapshot?: DelegationBudgetSnapshot;
|
|
22
|
+
verifications?: VerificationRecord[];
|
|
15
23
|
}
|
|
16
24
|
export declare function runsPath(dir: string): string;
|
|
17
25
|
export declare function startTrace(dir: string, command: string, args: Record<string, unknown>, session_id?: string): RunTrace;
|
|
@@ -19,7 +27,16 @@ export declare function endTrace(dir: string, run_id: string, status: Exclude<Ru
|
|
|
19
27
|
export declare function touchFile(dir: string, run_id: string, filePath: string): void;
|
|
20
28
|
export declare function setRiskScore(dir: string, run_id: string, score: number): void;
|
|
21
29
|
export declare function getTrace(dir: string, run_id: string): RunTrace | null;
|
|
30
|
+
export declare function recordBudget(dir: string, run_id: string, snapshot: DelegationBudgetSnapshot): void;
|
|
22
31
|
export declare function listTraces(dir: string, limit?: number): RunTrace[];
|
|
32
|
+
/**
|
|
33
|
+
* Return the most recent running trace for a session, or undefined if none.
|
|
34
|
+
*/
|
|
35
|
+
export declare function findRunningTrace(dir: string, sessionID: string): RunTrace | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Append a verification record to the run trace.
|
|
38
|
+
*/
|
|
39
|
+
export declare function recordVerification(dir: string, run_id: string, kind: string, evidence: string): void;
|
|
23
40
|
export interface RunDiff {
|
|
24
41
|
run_a: string;
|
|
25
42
|
run_b: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-trace.d.ts","sourceRoot":"","sources":["../../src/services/run-trace.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-trace.d.ts","sourceRoot":"","sources":["../../src/services/run-trace.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAEnE,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,GAAG,WAAW,CAAA;AAEvE,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,SAAS,CAAA;IACjB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,eAAe,CAAC,EAAE,wBAAwB,CAAA;IAC1C,aAAa,CAAC,EAAE,kBAAkB,EAAE,CAAA;CACrC;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,wBAAgB,UAAU,CACxB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,UAAU,SAAc,GACvB,QAAQ,CAiBV;AAqBD,wBAAgB,QAAQ,CACtB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,EACrC,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,GACb,IAAI,CAYN;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAS7E;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAM7E;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAErE;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,wBAAwB,GAAG,IAAI,CAMlG;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,QAAQ,EAAE,CAG9D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAGrF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,IAAI,CAaN;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,cAAc,EAAE,OAAO,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,eAAe,EAAE,OAAO,CAAA;CACzB;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAkB1F"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State Persistence Service
|
|
3
|
+
*
|
|
4
|
+
* Facade over run-trace, agent-trace-graph, and workflow-scorecard.
|
|
5
|
+
* Manages RunContext lifecycle and agent span tracking.
|
|
6
|
+
*/
|
|
7
|
+
import type { RunContext, AgentSpan, SpanStatus, SpanCloseOpts } from "./harness-types";
|
|
8
|
+
export interface StatePersistenceService {
|
|
9
|
+
startRun(command: string, args: Record<string, unknown>, sessionID: string): RunContext;
|
|
10
|
+
endRun(ctx: RunContext, status: "complete" | "failed" | "cancelled", outcome?: string, error?: string, scorecardInput?: import("./workflow-scorecard").ScorecardInput): void;
|
|
11
|
+
openAgentSpan(ctx: RunContext, parentSpanId: string | undefined, agent: string, task: string, stage: string): AgentSpan;
|
|
12
|
+
closeAgentSpan(spanId: string, status: SpanStatus, opts?: SpanCloseOpts): void;
|
|
13
|
+
recordObservation(ctx: RunContext, type: string, content: string): void;
|
|
14
|
+
getRunContext(sessionID: string): RunContext | undefined;
|
|
15
|
+
updateRunContext(ctx: RunContext): void;
|
|
16
|
+
}
|
|
17
|
+
export interface StatePersistenceOptions {
|
|
18
|
+
directory: string;
|
|
19
|
+
appLog?: (msg: string) => void;
|
|
20
|
+
}
|
|
21
|
+
export declare function createStatePersistence(options: StatePersistenceOptions): StatePersistenceService;
|
|
22
|
+
//# sourceMappingURL=state-persistence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-persistence.d.ts","sourceRoot":"","sources":["../../src/services/state-persistence.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAKvF,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,UAAU,CAAA;IACvF,MAAM,CACJ,GAAG,EAAE,UAAU,EACf,MAAM,EAAE,UAAU,GAAG,QAAQ,GAAG,WAAW,EAC3C,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,EACd,cAAc,CAAC,EAAE,OAAO,sBAAsB,EAAE,cAAc,GAC7D,IAAI,CAAA;IACP,aAAa,CACX,GAAG,EAAE,UAAU,EACf,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ,SAAS,CAAA;IACZ,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,IAAI,CAAA;IAC9E,iBAAiB,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACvE,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAA;IACxD,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAAA;CACxC;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CAC/B;AAID,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,GAAG,uBAAuB,CA4GhG"}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* - It returns a structured decision
|
|
15
15
|
* - It NEVER creates or modifies commands or workflows
|
|
16
16
|
*/
|
|
17
|
+
import type { PolicyDecision, PolicyInput } from "./harness-types";
|
|
17
18
|
/**
|
|
18
19
|
* The canonical set of registered FlowDeck commands.
|
|
19
20
|
* This list is derived from src/commands/*.md at build time and must NOT
|
|
@@ -113,6 +114,14 @@ export declare function isRegisteredTarget(name: string): {
|
|
|
113
114
|
* the requested target is not registered.
|
|
114
115
|
*/
|
|
115
116
|
export declare function runSupervisorReview(directory: string, targetName: string, ctx?: SupervisorContext, clarificationQuestion?: string): SupervisorDecision;
|
|
117
|
+
/**
|
|
118
|
+
* Review a tool call target through the supervisor lens.
|
|
119
|
+
*
|
|
120
|
+
* Returns a PolicyDecision so the harness can treat supervisor review like
|
|
121
|
+
* any other policy layer. `revise` and `escalate` are surfaced as `ask`
|
|
122
|
+
* verdicts; `block` is a `deny`; `approve` is an `allow`.
|
|
123
|
+
*/
|
|
124
|
+
export declare function reviewToolCall(directory: string, input: PolicyInput): PolicyDecision;
|
|
116
125
|
/**
|
|
117
126
|
* Shorthand: should execution proceed given a decision and the current config mode?
|
|
118
127
|
* In "advisory" mode, only "block" with a missing-existence check is hard-stopped.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supervisor-binding.d.ts","sourceRoot":"","sources":["../../src/services/supervisor-binding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;
|
|
1
|
+
{"version":3,"file":"supervisor-binding.d.ts","sourceRoot":"","sources":["../../src/services/supervisor-binding.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token Metrics
|
|
3
|
+
*
|
|
4
|
+
* Tracks per-run token usage from message.updated-style usage payloads and
|
|
5
|
+
* estimates cost. Used by the context ingress layer for real token budgets
|
|
6
|
+
* and by the context window monitor for usage warnings.
|
|
7
|
+
*/
|
|
8
|
+
export interface TokenUsageInfo {
|
|
9
|
+
input?: number;
|
|
10
|
+
output?: number;
|
|
11
|
+
reasoning?: number;
|
|
12
|
+
cache?: {
|
|
13
|
+
read?: number;
|
|
14
|
+
write?: number;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface RunUsageSnapshot {
|
|
18
|
+
runId: string;
|
|
19
|
+
totalTokens: number;
|
|
20
|
+
inputTokens: number;
|
|
21
|
+
outputTokens: number;
|
|
22
|
+
reasoningTokens: number;
|
|
23
|
+
cacheReadTokens: number;
|
|
24
|
+
cacheWriteTokens: number;
|
|
25
|
+
messageCount: number;
|
|
26
|
+
}
|
|
27
|
+
export declare const DEFAULT_INPUT_PRICE_PER_1M_TOKENS = 3;
|
|
28
|
+
export declare const DEFAULT_OUTPUT_PRICE_PER_1M_TOKENS = 15;
|
|
29
|
+
/** Record token usage from a single message.updated-like event. */
|
|
30
|
+
export declare function recordMessageUsage(runId: string, usage: TokenUsageInfo): void;
|
|
31
|
+
/** Return the accumulated usage for a run, or zeros if none recorded. */
|
|
32
|
+
export declare function getRunUsage(runId: string): RunUsageSnapshot;
|
|
33
|
+
/** Estimate cumulative cost in USD for a run. */
|
|
34
|
+
export declare function estimateCostUSD(runId: string): number;
|
|
35
|
+
/** Check whether a run's estimated cost exceeds a maximum budget. */
|
|
36
|
+
export declare function isOverBudget(runId: string, maxCost: number): boolean;
|
|
37
|
+
/** Clear all recorded usage (intended for tests). */
|
|
38
|
+
export declare function resetTokenMetrics(): void;
|
|
39
|
+
//# sourceMappingURL=token-metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-metrics.d.ts","sourceRoot":"","sources":["../../src/services/token-metrics.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE;QACN,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,CAAA;CACF;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,eAAe,EAAE,MAAM,CAAA;IACvB,eAAe,EAAE,MAAM,CAAA;IACvB,gBAAgB,EAAE,MAAM,CAAA;IACxB,YAAY,EAAE,MAAM,CAAA;CACrB;AAID,eAAO,MAAM,iCAAiC,IAAI,CAAA;AAClD,eAAO,MAAM,kCAAkC,KAAK,CAAA;AAqCpD,mEAAmE;AACnE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI,CAW7E;AAED,yEAAyE;AACzE,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAiB3D;AAED,iDAAiD;AACjD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOrD;AAED,qEAAqE;AACrE,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAEpE;AAED,qDAAqD;AACrD,wBAAgB,iBAAiB,IAAI,IAAI,CAExC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verification Layer
|
|
3
|
+
*
|
|
4
|
+
* Thin wrapper over command-validator, completion-validator, and
|
|
5
|
+
* agent-validator. Called by the harness controller after model outputs
|
|
6
|
+
* and before marking phases complete.
|
|
7
|
+
*/
|
|
8
|
+
import { type FullAuditResult } from "./command-validator";
|
|
9
|
+
import { type CompletionReadiness } from "../lib/completion-validator";
|
|
10
|
+
import { type ValidationResult } from "./agent-validator";
|
|
11
|
+
import type { RunContext } from "./harness-types";
|
|
12
|
+
import type { PlanningState } from "../tools/planning-state-lib";
|
|
13
|
+
export interface VerificationLayer {
|
|
14
|
+
/** Validate that a command reference in model output is registered. */
|
|
15
|
+
validateCommandRefs(text: string): FullAuditResult;
|
|
16
|
+
/** Validate completion readiness before allowing /fd-done. */
|
|
17
|
+
validateCompletion(state: PlanningState): CompletionReadiness;
|
|
18
|
+
/** Validate that an agent's output conforms to its contract fields. */
|
|
19
|
+
validateAgentOutput(agent: string, output: Record<string, unknown>): ValidationResult;
|
|
20
|
+
/** Record a verified outcome (test passed, review approved, etc.) to the run trace. */
|
|
21
|
+
recordVerification(ctx: RunContext, kind: string, evidence: string): void;
|
|
22
|
+
}
|
|
23
|
+
export declare function createVerificationLayer(directory: string): VerificationLayer;
|
|
24
|
+
//# sourceMappingURL=verification-layer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification-layer.d.ts","sourceRoot":"","sources":["../../src/services/verification-layer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACzE,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAuB,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAE9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAEhE,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAAA;IAClD,8DAA8D;IAC9D,kBAAkB,CAAC,KAAK,EAAE,aAAa,GAAG,mBAAmB,CAAA;IAC7D,uEAAuE;IACvE,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,gBAAgB,CAAA;IACrF,uFAAuF;IACvF,kBAAkB,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1E;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,CAkB5E"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Scores across 10 dimensions; stored in .codebase/SCORECARDS.jsonl for trend analysis.
|
|
5
5
|
*/
|
|
6
6
|
import type { RunTrace } from "./run-trace";
|
|
7
|
+
import type { AuditEntry } from "./harness-types";
|
|
7
8
|
export interface ScorecardDimensions {
|
|
8
9
|
/** Agents followed phase order and didn't skip required stages */
|
|
9
10
|
stageCompliance: number;
|
|
@@ -31,6 +32,8 @@ export interface ScorecardDimensions {
|
|
|
31
32
|
* Defaults to 1.0 when the supervisor is disabled or no reviews occurred.
|
|
32
33
|
*/
|
|
33
34
|
supervisorCompliance: number;
|
|
35
|
+
/** Overall governance adherence derived from audit entries */
|
|
36
|
+
governanceCompliance: number;
|
|
34
37
|
}
|
|
35
38
|
export interface WorkflowScorecard {
|
|
36
39
|
scorecard_id: string;
|
|
@@ -75,6 +78,8 @@ export interface ScorecardInput {
|
|
|
75
78
|
* Computed automatically from telemetry when omitted.
|
|
76
79
|
*/
|
|
77
80
|
supervisor_hard_stops?: number;
|
|
81
|
+
/** Audit entries for this run, used to score governance compliance. */
|
|
82
|
+
audit_entries?: AuditEntry[];
|
|
78
83
|
}
|
|
79
84
|
export declare function scorecardsPath(dir: string): string;
|
|
80
85
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-scorecard.d.ts","sourceRoot":"","sources":["../../src/services/workflow-scorecard.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAI3C,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,eAAe,EAAE,MAAM,CAAA;IACvB,uDAAuD;IACvD,qBAAqB,EAAE,MAAM,CAAA;IAC7B,uDAAuD;IACvD,aAAa,EAAE,MAAM,CAAA;IACrB,oDAAoD;IACpD,kBAAkB,EAAE,MAAM,CAAA;IAC1B,gDAAgD;IAChD,aAAa,EAAE,MAAM,CAAA;IACrB,iDAAiD;IACjD,eAAe,EAAE,MAAM,CAAA;IACvB,wCAAwC;IACxC,gBAAgB,EAAE,MAAM,CAAA;IACxB,0CAA0C;IAC1C,eAAe,EAAE,MAAM,CAAA;IACvB,uDAAuD;IACvD,cAAc,EAAE,MAAM,CAAA;IACtB,mCAAmC;IACnC,kBAAkB,EAAE,MAAM,CAAA;IAC1B;;;;OAIG;IACH,oBAAoB,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAA;IAClE,UAAU,EAAE,mBAAmB,CAAA;IAC/B,oDAAoD;IACpD,aAAa,EAAE,MAAM,CAAA;IACrB,iBAAiB,EAAE,MAAM,CAAA;IACzB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,cAAc,EAAE,MAAM,CAAA;IACtB,gBAAgB,EAAE,MAAM,CAAA;IACxB,kDAAkD;IAClD,kBAAkB,EAAE,MAAM,CAAA;IAC1B,4DAA4D;IAC5D,qBAAqB,EAAE,MAAM,CAAA;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,qDAAqD;IACrD,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,4CAA4C;IAC5C,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,iDAAiD;IACjD,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,4CAA4C;IAC5C,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"workflow-scorecard.d.ts","sourceRoot":"","sources":["../../src/services/workflow-scorecard.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAI3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,eAAe,EAAE,MAAM,CAAA;IACvB,uDAAuD;IACvD,qBAAqB,EAAE,MAAM,CAAA;IAC7B,uDAAuD;IACvD,aAAa,EAAE,MAAM,CAAA;IACrB,oDAAoD;IACpD,kBAAkB,EAAE,MAAM,CAAA;IAC1B,gDAAgD;IAChD,aAAa,EAAE,MAAM,CAAA;IACrB,iDAAiD;IACjD,eAAe,EAAE,MAAM,CAAA;IACvB,wCAAwC;IACxC,gBAAgB,EAAE,MAAM,CAAA;IACxB,0CAA0C;IAC1C,eAAe,EAAE,MAAM,CAAA;IACvB,uDAAuD;IACvD,cAAc,EAAE,MAAM,CAAA;IACtB,mCAAmC;IACnC,kBAAkB,EAAE,MAAM,CAAA;IAC1B;;;;OAIG;IACH,oBAAoB,EAAE,MAAM,CAAA;IAC5B,8DAA8D;IAC9D,oBAAoB,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAA;IAClE,UAAU,EAAE,mBAAmB,CAAA;IAC/B,oDAAoD;IACpD,aAAa,EAAE,MAAM,CAAA;IACrB,iBAAiB,EAAE,MAAM,CAAA;IACzB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,cAAc,EAAE,MAAM,CAAA;IACtB,gBAAgB,EAAE,MAAM,CAAA;IACxB,kDAAkD;IAClD,kBAAkB,EAAE,MAAM,CAAA;IAC1B,4DAA4D;IAC5D,qBAAqB,EAAE,MAAM,CAAA;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,qDAAqD;IACrD,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,4CAA4C;IAC5C,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,iDAAiD;IACjD,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,4CAA4C;IAC5C,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,uEAAuE;IACvE,aAAa,CAAC,EAAE,UAAU,EAAE,CAAA;CAC7B;AAiBD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAElD;AAiBD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,QAAQ,EACf,KAAK,GAAE,cAAmB,GACzB,iBAAiB,CA6EnB;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,iBAAiB,EAAE,CAS3E;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAEvF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,iBAAiB,EAAE,CAIhG;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIhF"}
|
|
@@ -11,6 +11,10 @@ export interface DecisionEntry {
|
|
|
11
11
|
alternatives_considered: string[];
|
|
12
12
|
risk_level: "low" | "medium" | "high";
|
|
13
13
|
agent?: string;
|
|
14
|
+
/** Policy reason that authorized or denied the change, when available. */
|
|
15
|
+
policy_reason?: string;
|
|
16
|
+
/** Audit entry id correlating this decision to the audit log. */
|
|
17
|
+
audit_entry_id?: string;
|
|
14
18
|
}
|
|
15
19
|
export declare const decisionTraceTool: ToolDefinition;
|
|
16
20
|
//# sourceMappingURL=decision-trace.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decision-trace.d.ts","sourceRoot":"","sources":["../../src/tools/decision-trace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAO/D,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAA;IACtD,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,uBAAuB,EAAE,MAAM,EAAE,CAAA;IACjC,UAAU,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAA;IACrC,KAAK,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"decision-trace.d.ts","sourceRoot":"","sources":["../../src/tools/decision-trace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAO/D,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAA;IACtD,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,uBAAuB,EAAE,MAAM,EAAE,CAAA;IACjC,UAAU,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAA;IACrC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,0EAA0E;IAC1E,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,iEAAiE;IACjE,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAgBD,eAAO,MAAM,iBAAiB,EAAE,cA4D9B,CAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delegate Tool
|
|
3
|
+
*
|
|
4
|
+
* Runtime delegation primitive for the orchestrator. Replaces raw @agent
|
|
5
|
+
* references with an explicit tool call that:
|
|
6
|
+
* - enforces delegation-budget.maxDepth
|
|
7
|
+
* - tracks parent-child spans in the agent trace graph
|
|
8
|
+
* - returns a structured DelegateResult
|
|
9
|
+
*/
|
|
10
|
+
import { type ToolDefinition } from "@opencode-ai/plugin";
|
|
11
|
+
import type { OpencodeClient } from "@opencode-ai/sdk";
|
|
12
|
+
import type { StatePersistenceService } from "../services/state-persistence";
|
|
13
|
+
import type { DelegateResult, DelegateToolArgs } from "../services/harness-types";
|
|
14
|
+
export type { DelegateResult, DelegateToolArgs };
|
|
15
|
+
export declare function createDelegateTool(client: OpencodeClient, statePersistence: StatePersistenceService): ToolDefinition;
|
|
16
|
+
//# sourceMappingURL=delegate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delegate.d.ts","sourceRoot":"","sources":["../../src/tools/delegate.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAGtD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAA;AAC5E,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAc,MAAM,2BAA2B,CAAA;AAG7F,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,CAAA;AAShD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,cAAc,EACtB,gBAAgB,EAAE,uBAAuB,GACxC,cAAc,CAqGhB"}
|
|
@@ -15,5 +15,13 @@ export interface FailureStore {
|
|
|
15
15
|
last_updated: string;
|
|
16
16
|
entries: FailureEntry[];
|
|
17
17
|
}
|
|
18
|
+
export interface FailureFilter {
|
|
19
|
+
type?: FailureEntry["type"];
|
|
20
|
+
path_prefix?: string;
|
|
21
|
+
tag?: string;
|
|
22
|
+
limit?: number;
|
|
23
|
+
}
|
|
24
|
+
export declare function queryFailures(directory: string, filter?: FailureFilter): FailureEntry[];
|
|
25
|
+
export declare function listFailures(directory: string, limit?: number): FailureEntry[];
|
|
18
26
|
export declare const failureReplayTool: ToolDefinition;
|
|
19
27
|
//# sourceMappingURL=failure-replay.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"failure-replay.d.ts","sourceRoot":"","sources":["../../src/tools/failure-replay.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAO/D,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,iBAAiB,GAAG,mBAAmB,GAAG,YAAY,GAAG,SAAS,GAAG,eAAe,CAAA;IAC1F,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,YAAY,EAAE,CAAA;CACxB;AAuBD,eAAO,MAAM,iBAAiB,EAAE,cA0E9B,CAAA"}
|
|
1
|
+
{"version":3,"file":"failure-replay.d.ts","sourceRoot":"","sources":["../../src/tools/failure-replay.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAO/D,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,iBAAiB,GAAG,mBAAmB,GAAG,YAAY,GAAG,SAAS,GAAG,eAAe,CAAA;IAC1F,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,YAAY,EAAE,CAAA;CACxB;AAuBD,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,YAAY,CAAC,MAAM,CAAC,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,GAAE,aAAkB,GAAG,YAAY,EAAE,CAW3F;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,YAAY,EAAE,CAK1E;AAED,eAAO,MAAM,iBAAiB,EAAE,cA0E9B,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy-engine.d.ts","sourceRoot":"","sources":["../../src/tools/policy-engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAO/D,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAA;IAC5B,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;
|
|
1
|
+
{"version":3,"file":"policy-engine.d.ts","sourceRoot":"","sources":["../../src/tools/policy-engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAO/D,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAA;IAC5B,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAMD,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,CAQxD;AASD,eAAO,MAAM,gBAAgB,EAAE,cAyE7B,CAAA"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# FlowDeck Target Harness Architecture
|
|
2
|
+
|
|
3
|
+
**Status**: Proposed
|
|
4
|
+
**Scope**: Transform FlowDeck from a prompt-heavy plugin into a real agent-harness engineering runtime while staying OpenCode-native.
|
|
5
|
+
|
|
6
|
+
## 1. Core idea
|
|
7
|
+
|
|
8
|
+
Today FlowDeck registers agents, rules, skills, commands, hooks and tools, but most critical behavior lives in prompts (orchestrator prompt, command markdown). Several runtime services exist as code and tests but are not wired into the plugin lifecycle. The target architecture moves three things into runtime enforcement:
|
|
9
|
+
|
|
10
|
+
1. **Delegation is explicit.** The orchestrator no longer "asks" the model to route; it calls a `delegate` tool that the harness executes, tracks, and budgets.
|
|
11
|
+
2. **Policy is executable.** Agent contracts, supervisor review, approval gates, and loop/deadlock detection run in hooks/services, not only in prompt text.
|
|
12
|
+
3. **State is first-class.** Workflow state, run traces, agent spans, approvals, and observations are persisted, queryable, and used for recovery, review, and audit.
|
|
13
|
+
|
|
14
|
+
The model is still the reasoner, but the harness owns execution, state, and governance.
|
|
15
|
+
|
|
16
|
+
## 2. Design principles
|
|
17
|
+
|
|
18
|
+
- **Correctness first**: use existing working services before inventing new ones.
|
|
19
|
+
- **OpenCode-native**: keep tools, permissions allow/deny/ask, agents, skills, hooks, and config.
|
|
20
|
+
- **Prompts describe, runtime enforces**: contracts, budgets, gates, and routing are checked in code.
|
|
21
|
+
- **Minimum surface area**: only expose what callers (agents/commands) need.
|
|
22
|
+
- **Testable layers**: each layer has narrow interfaces and can be exercised without the full OpenCode runtime.
|
|
23
|
+
|
|
24
|
+
## 3. High-level component diagram
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
28
|
+
│ OpenCode host │
|
|
29
|
+
│ (model, session, native tools, permissions, agents, commands, skills) │
|
|
30
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
31
|
+
│
|
|
32
|
+
▼
|
|
33
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
34
|
+
│ FlowDeck plugin (src/index.ts) │
|
|
35
|
+
│ registers agents, tools, hooks, MCPs, commands, skills, rules │
|
|
36
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
37
|
+
│
|
|
38
|
+
┌───────────────────────────┼───────────────────────────┐
|
|
39
|
+
▼ ▼ ▼
|
|
40
|
+
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
|
41
|
+
│ ContextIngress│ │ ActionMediator│ │ExecutionSubstrate
|
|
42
|
+
│ Service │ │ Service │ │ Service │
|
|
43
|
+
└───────┬───────┘ └───────┬───────┘ └───────┬───────┘
|
|
44
|
+
│ │ │
|
|
45
|
+
▼ ▼ ▼
|
|
46
|
+
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
|
47
|
+
│StatePersistence│ │Verification& │ │Recovery& │
|
|
48
|
+
│ Service │ │ Review │ │ Debugging │
|
|
49
|
+
└───────┬───────┘ └───────┬───────┘ └───────┬───────┘
|
|
50
|
+
│ │ │
|
|
51
|
+
└──────────────────────────┼──────────────────────────┘
|
|
52
|
+
▼
|
|
53
|
+
┌─────────────────────────────┐
|
|
54
|
+
│ Delegation & Coordination │
|
|
55
|
+
│ (orchestrator + router) │
|
|
56
|
+
└─────────────────────────────┘
|
|
57
|
+
│
|
|
58
|
+
▼
|
|
59
|
+
┌─────────────────────────────┐
|
|
60
|
+
│ Governance & Audit │
|
|
61
|
+
│ (contracts, approvals, logs)│
|
|
62
|
+
└─────────────────────────────┘
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 4. End-to-end data flow
|
|
66
|
+
|
|
67
|
+
A typical user request (`/fd-quick "add auth middleware"`) flows through the harness:
|
|
68
|
+
|
|
69
|
+
1. **Command entry** — OpenCode fires `command.execute.before`/`after`. The harness starts a `RunTrace` (run_id).
|
|
70
|
+
2. **Context ingress** — `ContextIngressService` assembles `STATE.md`, `PLAN.md`, `.codebase/` docs, recent events, relevant skills/rules, and a token-budget snapshot. It short-circuits to the trivial-chat path if the request is a simple question.
|
|
71
|
+
3. **Routing** — `quick-router` + `workflow-router` classify the task and produce a `WorkflowRoute` (workflow class + stage sequence). `model-router` provides complexity/eligible-agent hints.
|
|
72
|
+
4. **Delegation** — The orchestrator calls the `delegate` tool. `ActionMediator` validates the target agent against `agent-contract-registry`, runs `agent-validator`, checks `supervisor-binding`, and enforces the delegation budget.
|
|
73
|
+
5. **Execution** — `ExecutionSubstrate` opens an `AgentSpan` (agent-trace-graph), tracks the child session, applies tool lifecycle hooks, and records cost/time.
|
|
74
|
+
6. **Tool mediation** — On every `tool.execute.before`, `ActionMediator` normalizes args, classifies risk, runs approval gates (`approval-manager`), arch constraints, phase gates, loop detection, and orchestrator guard.
|
|
75
|
+
7. **State persistence** — Each meaningful change writes to `.planning/STATE.md`, `.codebase/RUNS.jsonl`, `.codebase/AGENT_SPANS.jsonl`, `.opencode/flowdeck-events.jsonl`, or `.codebase/APPROVALS.json`.
|
|
76
|
+
8. **Verification** — At stage boundaries `VerificationService` checks tests, coverage, review verdict, and design approval before allowing the next stage.
|
|
77
|
+
9. **Recovery** — If a span fails or a deadlock/loop signal fires, `RecoveryService` classifies the failure, bounds retries, and either re-routes, escalates, or stops.
|
|
78
|
+
10. **Audit** — On run end, `WorkflowScorecard` is generated and `AGENT_PERF.json` is updated.
|
|
79
|
+
|
|
80
|
+
## 5. Key interface contracts
|
|
81
|
+
|
|
82
|
+
These interfaces are the contracts between layers. Implementations may be added incrementally.
|
|
83
|
+
|
|
84
|
+
### 5.1 Context ingress
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
// src/services/context-ingress.ts
|
|
88
|
+
export interface AssembledContext {
|
|
89
|
+
runId: string;
|
|
90
|
+
sessionId: string;
|
|
91
|
+
projectRoot: string;
|
|
92
|
+
state: PlanningState;
|
|
93
|
+
route: WorkflowRoute | null;
|
|
94
|
+
relevantRules: string[];
|
|
95
|
+
relevantSkills: string[];
|
|
96
|
+
recentEvents: ToolEvent[];
|
|
97
|
+
observations: Observation[];
|
|
98
|
+
tokenBudget: TokenBudgetSnapshot;
|
|
99
|
+
isTrivialChat: boolean;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface ContextIngressService {
|
|
103
|
+
assemble(input: { command: string; args: string; sessionId: string }): Promise<AssembledContext>;
|
|
104
|
+
refreshRunId(ctx: AssembledContext): AssembledContext;
|
|
105
|
+
snapshotBudget(ctx: AssembledContext): TokenBudgetSnapshot;
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 5.2 Action mediator
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
// src/services/action-mediator.ts
|
|
113
|
+
export interface ActionRequest {
|
|
114
|
+
toolName: string;
|
|
115
|
+
args: Record<string, unknown>;
|
|
116
|
+
agentName?: string;
|
|
117
|
+
runId: string;
|
|
118
|
+
sessionId: string;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface ActionDecision {
|
|
122
|
+
action: "allow" | "block" | "ask" | "escalate";
|
|
123
|
+
reason: string;
|
|
124
|
+
riskScore: number;
|
|
125
|
+
requiredApprovalId?: string;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface ActionMediatorService {
|
|
129
|
+
check(request: ActionRequest): ActionDecision;
|
|
130
|
+
recordOutcome(request: ActionRequest, decision: ActionDecision, output: unknown): void;
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### 5.3 Delegation
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
// src/tools/delegate.ts
|
|
138
|
+
export interface DelegateInput {
|
|
139
|
+
target: "agent" | "command";
|
|
140
|
+
name: string; // e.g. "backend-coder" or "fd-plan"
|
|
141
|
+
taskDescription: string;
|
|
142
|
+
contextSummary?: string;
|
|
143
|
+
mode?: "quick" | "standard" | "explore" | "verify-heavy";
|
|
144
|
+
parentSpanId?: string;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export interface DelegateResult {
|
|
148
|
+
spanId: string;
|
|
149
|
+
childSessionId?: string;
|
|
150
|
+
status: "running" | "blocked" | "escalated";
|
|
151
|
+
reason?: string;
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### 5.4 Run pipeline
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
// src/tools/run-pipeline.ts
|
|
159
|
+
export interface RunPipelineInput {
|
|
160
|
+
workflowClass: WorkflowClass;
|
|
161
|
+
stages?: string[]; // optional override
|
|
162
|
+
taskDescription: string;
|
|
163
|
+
confirm?: boolean;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export interface RunPipelineResult {
|
|
167
|
+
runId: string;
|
|
168
|
+
completedStages: string[];
|
|
169
|
+
currentStage: string | null;
|
|
170
|
+
blocked: boolean;
|
|
171
|
+
blockedReason?: string;
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### 5.5 Delegation budget
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
// src/services/delegation-budget.ts
|
|
179
|
+
export interface DelegationBudget {
|
|
180
|
+
runId: string;
|
|
181
|
+
maxToolCalls: number;
|
|
182
|
+
maxDepth: number;
|
|
183
|
+
maxSameStepRetries: number;
|
|
184
|
+
spentToolCalls: number;
|
|
185
|
+
currentDepth: number;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export interface DelegationBudgetService {
|
|
189
|
+
init(runId: string, config?: Partial<DelegationBudget>): DelegationBudget;
|
|
190
|
+
checkSpend(runId: string, toolName: string): { ok: boolean; remaining: number };
|
|
191
|
+
recordDelegation(parentRunId: string, childRunId: string): boolean;
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## 6. State files
|
|
196
|
+
|
|
197
|
+
| File | Owner | Purpose | Lifecycle |
|
|
198
|
+
|------|-------|---------|-----------|
|
|
199
|
+
| `.planning/STATE.md` | `planning-state` tool | Current phase, plan confirmation, design gates | Long-lived, updated per phase |
|
|
200
|
+
| `.planning/PLAN.md` | `planning-state` tool | Numbered plan steps | Long-lived, created per feature |
|
|
201
|
+
| `.codebase/RUNS.jsonl` | `run-trace` service | Command-level run history | Append-only |
|
|
202
|
+
| `.codebase/AGENT_SPANS.jsonl` | `agent-trace-graph` service | Causal agent delegation spans | Append-only |
|
|
203
|
+
| `.codebase/SCORECARDS.jsonl` | `workflow-scorecard` service | 10-dimension run quality scores | Append-only |
|
|
204
|
+
| `.codebase/DEADLOCK_SIGNALS.jsonl` | `deadlock-detector` service | Detected loop/deadlock signals | Append-only |
|
|
205
|
+
| `.codebase/APPROVALS.json` | `approval-manager` service | Pending/approved sensitive operations | Mutable |
|
|
206
|
+
| `.codebase/AGENT_PERF.json` | `agent-performance` service | Per-agent/model/task success stats | Mutable |
|
|
207
|
+
| `.codebase/WORKFLOW_ROUTING.jsonl` | `workflow-router` service | Routing decisions and escalations | Append-only |
|
|
208
|
+
| `.opencode/flowdeck-events.jsonl` | `event-logger` service | Raw tool/session events | Append-only, rotated |
|
|
209
|
+
|
|
210
|
+
## 7. Failure modes and recovery
|
|
211
|
+
|
|
212
|
+
| Failure | Detection | Recovery |
|
|
213
|
+
|---------|-----------|----------|
|
|
214
|
+
| Same tool repeated with same result | `LoopDetector` in `tool.execute.before` | Block + escalation message |
|
|
215
|
+
| Agent bounce / circular delegation | `deadlock-detector` over `AGENT_SPANS.jsonl` | Log signal, auto-stop if configured |
|
|
216
|
+
| Budget exhausted | `DelegationBudgetService` | Warn / stop / escalate based on `governance.costBudget.onExhaustion` |
|
|
217
|
+
| Approval missing | `approval-hook` + `ActionMediator` | Block with `APPROVAL_REQUIRED` and approval id |
|
|
218
|
+
| Contract violation | `agent-validator` | Advisory warning or strict block |
|
|
219
|
+
| Child session error | `event` hook `session.error` | Close span as `failed`, surface to parent |
|
|
220
|
+
| Tool persistence failure | `event-logger` health flag | Loop detection falls back to in-memory, logs warning |
|
|
221
|
+
| Unregistered target | `supervisor-binding` + `command-validator` | Block before execution |
|
|
222
|
+
|
|
223
|
+
## 8. Security considerations
|
|
224
|
+
|
|
225
|
+
- Secrets never enter state files; event args are sanitized by `sanitizeArgs`.
|
|
226
|
+
- Sensitive paths require explicit approval stored in `.codebase/APPROVALS.json` with TTL.
|
|
227
|
+
- Orchestrator cannot use write/edit/bash tools; `OrchestratorGuard` throws.
|
|
228
|
+
- Arch constraints in `.codebase/CONSTRAINTS.md` block edits to forbidden paths.
|
|
229
|
+
- Phase gates block implementation during discuss/plan phases.
|
|
230
|
+
- Tool guard blocks dangerous bash/read/write patterns when enabled.
|
|
231
|
+
|
|
232
|
+
## 9. Migration path
|
|
233
|
+
|
|
234
|
+
The harness is built incrementally. Each layer can be merged independently:
|
|
235
|
+
|
|
236
|
+
1. Wire existing unwired services into `src/index.ts` (agent validator, trace graph, run trace, scorecard, deadlock detector, delegation budget). Existing behavior remains opt-in or advisory.
|
|
237
|
+
2. Add `delegate` and `run-pipeline` tools behind feature flags; keep markdown commands as fallback.
|
|
238
|
+
3. Replace prompt-based routing directives with tool calls once delegation is stable.
|
|
239
|
+
4. Promote governance from advisory to strict via `flowdeck.json`.
|
|
240
|
+
|
|
241
|
+
No existing public API is broken in step 1.
|