@gajae-code/coding-agent 0.2.5 → 0.3.1
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/CHANGELOG.md +28 -0
- package/dist/types/async/job-manager.d.ts +91 -2
- package/dist/types/cli/args.d.ts +1 -1
- package/dist/types/commands/deep-interview.d.ts +3 -0
- package/dist/types/commands/harness.d.ts +37 -0
- package/dist/types/config/keybindings.d.ts +5 -0
- package/dist/types/config/settings-schema.d.ts +10 -4
- package/dist/types/config/settings.d.ts +2 -0
- package/dist/types/debug/crash-diagnostics.d.ts +45 -0
- package/dist/types/debug/runtime-gauges.d.ts +6 -0
- package/dist/types/deep-interview/render-middleware.d.ts +6 -0
- package/dist/types/eval/py/executor.d.ts +2 -0
- package/dist/types/eval/py/kernel.d.ts +2 -0
- package/dist/types/exec/bash-executor.d.ts +10 -0
- package/dist/types/extensibility/custom-tools/types.d.ts +1 -0
- package/dist/types/extensibility/extensions/types.d.ts +6 -0
- package/dist/types/extensibility/shared-events.d.ts +1 -0
- package/dist/types/gjc-runtime/cli-write-receipt.d.ts +24 -0
- package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +1 -0
- package/dist/types/gjc-runtime/state-graph.d.ts +4 -0
- package/dist/types/gjc-runtime/state-migrations.d.ts +33 -0
- package/dist/types/gjc-runtime/state-renderer.d.ts +65 -0
- package/dist/types/gjc-runtime/state-runtime.d.ts +2 -0
- package/dist/types/gjc-runtime/state-schema.d.ts +317 -0
- package/dist/types/gjc-runtime/state-validation.d.ts +6 -0
- package/dist/types/gjc-runtime/state-writer.d.ts +147 -0
- package/dist/types/gjc-runtime/team-runtime.d.ts +81 -7
- package/dist/types/gjc-runtime/workflow-command-ref.d.ts +43 -0
- package/dist/types/gjc-runtime/workflow-manifest.d.ts +54 -0
- package/dist/types/harness-control-plane/classifier.d.ts +13 -0
- package/dist/types/harness-control-plane/control-endpoint.d.ts +31 -0
- package/dist/types/harness-control-plane/finalize.d.ts +47 -0
- package/dist/types/harness-control-plane/frame-mapper.d.ts +29 -0
- package/dist/types/harness-control-plane/operate.d.ts +35 -0
- package/dist/types/harness-control-plane/owner.d.ts +46 -0
- package/dist/types/harness-control-plane/preserve.d.ts +19 -0
- package/dist/types/harness-control-plane/receipts.d.ts +88 -0
- package/dist/types/harness-control-plane/rpc-adapter.d.ts +66 -0
- package/dist/types/harness-control-plane/seams.d.ts +21 -0
- package/dist/types/harness-control-plane/session-lease.d.ts +65 -0
- package/dist/types/harness-control-plane/state-machine.d.ts +19 -0
- package/dist/types/harness-control-plane/storage.d.ts +53 -0
- package/dist/types/harness-control-plane/types.d.ts +162 -0
- package/dist/types/hooks/skill-keywords.d.ts +2 -1
- package/dist/types/hooks/skill-state.d.ts +23 -29
- package/dist/types/internal-urls/agent-protocol.d.ts +2 -2
- package/dist/types/internal-urls/artifact-protocol.d.ts +2 -2
- package/dist/types/internal-urls/registry-helpers.d.ts +8 -7
- package/dist/types/internal-urls/types.d.ts +4 -0
- package/dist/types/lsp/index.d.ts +10 -10
- package/dist/types/modes/bridge/auth.d.ts +12 -0
- package/dist/types/modes/bridge/bridge-client-bridge.d.ts +9 -0
- package/dist/types/modes/bridge/bridge-mode.d.ts +44 -0
- package/dist/types/modes/bridge/bridge-ui-context.d.ts +88 -0
- package/dist/types/modes/bridge/event-stream.d.ts +8 -0
- package/dist/types/modes/components/custom-editor.d.ts +6 -0
- package/dist/types/modes/components/hook-selector.d.ts +1 -0
- package/dist/types/modes/components/jobs-overlay-model.d.ts +31 -0
- package/dist/types/modes/components/jobs-overlay.d.ts +30 -0
- package/dist/types/modes/components/status-line/types.d.ts +2 -0
- package/dist/types/modes/components/status-line.d.ts +2 -0
- package/dist/types/modes/controllers/input-controller.d.ts +1 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +8 -0
- package/dist/types/modes/index.d.ts +1 -0
- package/dist/types/modes/interactive-mode.d.ts +2 -0
- package/dist/types/modes/jobs-observer.d.ts +57 -0
- package/dist/types/modes/rpc/host-tools.d.ts +1 -16
- package/dist/types/modes/rpc/host-uris.d.ts +1 -38
- package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +20 -0
- package/dist/types/modes/shared/agent-wire/command-validation.d.ts +2 -0
- package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +24 -0
- package/dist/types/modes/shared/agent-wire/handshake.d.ts +46 -0
- package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +16 -0
- package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +17 -0
- package/dist/types/modes/shared/agent-wire/protocol.d.ts +44 -0
- package/dist/types/modes/shared/agent-wire/responses.d.ts +4 -0
- package/dist/types/modes/shared/agent-wire/scopes.d.ts +18 -0
- package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +42 -0
- package/dist/types/modes/shared/agent-wire/ui-result.d.ts +27 -0
- package/dist/types/modes/types.d.ts +2 -0
- package/dist/types/sdk.d.ts +4 -0
- package/dist/types/session/agent-session.d.ts +19 -1
- package/dist/types/skill-state/active-state.d.ts +2 -0
- package/dist/types/skill-state/deep-interview-mutation-guard.d.ts +1 -1
- package/dist/types/skill-state/workflow-state-contract.d.ts +25 -2
- package/dist/types/skill-state/workflow-state-version.d.ts +3 -0
- package/dist/types/task/executor.d.ts +3 -0
- package/dist/types/task/id.d.ts +7 -0
- package/dist/types/task/index.d.ts +5 -0
- package/dist/types/task/receipt.d.ts +85 -0
- package/dist/types/task/spawn-gate.d.ts +38 -0
- package/dist/types/task/types.d.ts +198 -14
- package/dist/types/tools/cron.d.ts +6 -0
- package/dist/types/tools/index.d.ts +2 -0
- package/dist/types/tools/path-utils.d.ts +1 -0
- package/dist/types/tools/subagent.d.ts +26 -1
- package/package.json +7 -7
- package/scripts/build-binary.ts +7 -0
- package/src/async/job-manager.ts +334 -6
- package/src/cli/args.ts +9 -2
- package/src/cli/auth-broker-cli.ts +1 -0
- package/src/cli/config-cli.ts +10 -2
- package/src/cli.ts +2 -0
- package/src/commands/deep-interview.ts +1 -0
- package/src/commands/harness.ts +862 -0
- package/src/commands/launch.ts +2 -2
- package/src/commands/state.ts +2 -1
- package/src/commands/team.ts +54 -39
- package/src/config/keybindings.ts +6 -0
- package/src/config/settings-schema.ts +13 -3
- package/src/config/settings.ts +5 -0
- package/src/dap/client.ts +17 -3
- package/src/debug/crash-diagnostics.ts +223 -0
- package/src/debug/runtime-gauges.ts +20 -0
- package/src/deep-interview/render-middleware.ts +372 -0
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +1 -1
- package/src/defaults/gjc/skills/ralplan/SKILL.md +31 -2
- package/src/defaults/gjc/skills/team/SKILL.md +47 -21
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +106 -13
- package/src/eval/py/executor.ts +21 -1
- package/src/eval/py/kernel.ts +15 -0
- package/src/exec/bash-executor.ts +41 -0
- package/src/extensibility/custom-tools/types.ts +1 -0
- package/src/extensibility/extensions/types.ts +6 -0
- package/src/extensibility/shared-events.ts +1 -0
- package/src/gjc-runtime/cli-write-receipt.ts +31 -0
- package/src/gjc-runtime/deep-interview-runtime.ts +98 -42
- package/src/gjc-runtime/goal-mode-request.ts +11 -3
- package/src/gjc-runtime/ralplan-runtime.ts +235 -43
- package/src/gjc-runtime/state-graph.ts +86 -0
- package/src/gjc-runtime/state-migrations.ts +179 -0
- package/src/gjc-runtime/state-renderer.ts +345 -0
- package/src/gjc-runtime/state-runtime.ts +1155 -46
- package/src/gjc-runtime/state-schema.ts +192 -0
- package/src/gjc-runtime/state-validation.ts +49 -0
- package/src/gjc-runtime/state-writer.ts +749 -0
- package/src/gjc-runtime/team-runtime.ts +1255 -189
- package/src/gjc-runtime/ultragoal-runtime.ts +460 -43
- package/src/gjc-runtime/workflow-command-ref.ts +239 -0
- package/src/gjc-runtime/workflow-manifest.generated.json +1601 -0
- package/src/gjc-runtime/workflow-manifest.ts +427 -0
- package/src/harness-control-plane/classifier.ts +128 -0
- package/src/harness-control-plane/control-endpoint.ts +148 -0
- package/src/harness-control-plane/finalize.ts +222 -0
- package/src/harness-control-plane/frame-mapper.ts +286 -0
- package/src/harness-control-plane/operate.ts +225 -0
- package/src/harness-control-plane/owner.ts +600 -0
- package/src/harness-control-plane/preserve.ts +102 -0
- package/src/harness-control-plane/receipts.ts +216 -0
- package/src/harness-control-plane/rpc-adapter.ts +276 -0
- package/src/harness-control-plane/seams.ts +39 -0
- package/src/harness-control-plane/session-lease.ts +388 -0
- package/src/harness-control-plane/state-machine.ts +98 -0
- package/src/harness-control-plane/storage.ts +257 -0
- package/src/harness-control-plane/types.ts +214 -0
- package/src/hooks/skill-keywords.ts +4 -2
- package/src/hooks/skill-state.ts +197 -64
- package/src/internal-urls/agent-protocol.ts +68 -21
- package/src/internal-urls/artifact-protocol.ts +12 -17
- package/src/internal-urls/docs-index.generated.ts +3 -2
- package/src/internal-urls/registry-helpers.ts +19 -16
- package/src/internal-urls/types.ts +4 -0
- package/src/lsp/client.ts +18 -2
- package/src/main.ts +21 -5
- package/src/modes/bridge/auth.ts +41 -0
- package/src/modes/bridge/bridge-client-bridge.ts +47 -0
- package/src/modes/bridge/bridge-mode.ts +520 -0
- package/src/modes/bridge/bridge-ui-context.ts +200 -0
- package/src/modes/bridge/event-stream.ts +70 -0
- package/src/modes/components/assistant-message.ts +5 -1
- package/src/modes/components/custom-editor.ts +101 -0
- package/src/modes/components/hook-selector.ts +133 -20
- package/src/modes/components/jobs-overlay-model.ts +109 -0
- package/src/modes/components/jobs-overlay.ts +172 -0
- package/src/modes/components/status-line/presets.ts +7 -5
- package/src/modes/components/status-line/segments.ts +25 -0
- package/src/modes/components/status-line/types.ts +2 -0
- package/src/modes/components/status-line.ts +9 -1
- package/src/modes/controllers/event-controller.ts +71 -6
- package/src/modes/controllers/extension-ui-controller.ts +43 -1
- package/src/modes/controllers/input-controller.ts +105 -9
- package/src/modes/controllers/selector-controller.ts +31 -1
- package/src/modes/index.ts +1 -0
- package/src/modes/interactive-mode.ts +28 -0
- package/src/modes/jobs-observer.ts +204 -0
- package/src/modes/rpc/host-tools.ts +1 -186
- package/src/modes/rpc/host-uris.ts +1 -235
- package/src/modes/rpc/rpc-client.ts +25 -10
- package/src/modes/rpc/rpc-mode.ts +12 -381
- package/src/modes/shared/agent-wire/command-dispatch.ts +341 -0
- package/src/modes/shared/agent-wire/command-validation.ts +131 -0
- package/src/modes/shared/agent-wire/event-envelope.ts +108 -0
- package/src/modes/shared/agent-wire/handshake.ts +117 -0
- package/src/modes/shared/agent-wire/host-tool-bridge.ts +194 -0
- package/src/modes/shared/agent-wire/host-uri-bridge.ts +236 -0
- package/src/modes/shared/agent-wire/protocol.ts +96 -0
- package/src/modes/shared/agent-wire/responses.ts +17 -0
- package/src/modes/shared/agent-wire/scopes.ts +89 -0
- package/src/modes/shared/agent-wire/ui-request-broker.ts +150 -0
- package/src/modes/shared/agent-wire/ui-result.ts +48 -0
- package/src/modes/types.ts +2 -0
- package/src/prompts/agents/executor.md +13 -0
- package/src/prompts/tools/subagent.md +39 -4
- package/src/prompts/tools/task-summary.md +3 -9
- package/src/prompts/tools/task.md +5 -1
- package/src/sdk.ts +8 -0
- package/src/session/agent-session.ts +445 -71
- package/src/session/session-manager.ts +13 -1
- package/src/skill-state/active-state.ts +58 -65
- package/src/skill-state/deep-interview-mutation-guard.ts +114 -17
- package/src/skill-state/initial-phase.ts +2 -0
- package/src/skill-state/workflow-state-contract.ts +33 -4
- package/src/skill-state/workflow-state-version.ts +3 -0
- package/src/slash-commands/builtin-registry.ts +8 -0
- package/src/task/executor.ts +79 -13
- package/src/task/id.ts +33 -0
- package/src/task/index.ts +376 -74
- package/src/task/output-manager.ts +5 -4
- package/src/task/receipt.ts +297 -0
- package/src/task/render.ts +54 -134
- package/src/task/spawn-gate.ts +132 -0
- package/src/task/types.ts +104 -10
- package/src/tools/ask.ts +88 -27
- package/src/tools/ast-edit.ts +1 -0
- package/src/tools/ast-grep.ts +1 -0
- package/src/tools/bash.ts +1 -1
- package/src/tools/cron.ts +48 -0
- package/src/tools/find.ts +4 -1
- package/src/tools/index.ts +2 -0
- package/src/tools/path-utils.ts +3 -2
- package/src/tools/read.ts +1 -0
- package/src/tools/search.ts +1 -0
- package/src/tools/skill.ts +6 -1
- package/src/tools/subagent.ts +423 -79
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript is the authoritative source of truth for GJC workflow manifests.
|
|
3
|
+
* Any JSON manifest projection is derived from this module and must never be
|
|
4
|
+
* hand-edited.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { CanonicalGjcWorkflowSkill } from "../skill-state/active-state";
|
|
8
|
+
import { CANONICAL_GJC_WORKFLOW_SKILLS } from "../skill-state/active-state";
|
|
9
|
+
import { initialPhaseForSkill } from "../skill-state/initial-phase";
|
|
10
|
+
|
|
11
|
+
export interface WorkflowState {
|
|
12
|
+
id: string;
|
|
13
|
+
initial?: boolean;
|
|
14
|
+
terminal?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface WorkflowTransition {
|
|
18
|
+
from: string;
|
|
19
|
+
to: string;
|
|
20
|
+
verb: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface WorkflowVerb {
|
|
24
|
+
name: string;
|
|
25
|
+
planned?: boolean;
|
|
26
|
+
/** Invocation surface that exposes this verb in the real CLI parser. */
|
|
27
|
+
surface?: "state-action" | "command-positional" | "command-flag";
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface TypedArgSpec {
|
|
31
|
+
name: string;
|
|
32
|
+
type: "string" | "number" | "boolean" | "enum" | "object";
|
|
33
|
+
enumValues?: string[];
|
|
34
|
+
required?: boolean;
|
|
35
|
+
appliesToVerbs?: string[];
|
|
36
|
+
planned?: boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface RetentionPolicy {
|
|
40
|
+
category: string;
|
|
41
|
+
keep?: number;
|
|
42
|
+
maxAgeDays?: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface SkillManifest {
|
|
46
|
+
skill: CanonicalGjcWorkflowSkill;
|
|
47
|
+
states: WorkflowState[];
|
|
48
|
+
initialState: string;
|
|
49
|
+
terminalStates: string[];
|
|
50
|
+
transitions: WorkflowTransition[];
|
|
51
|
+
verbs: WorkflowVerb[];
|
|
52
|
+
typedArgs: TypedArgSpec[];
|
|
53
|
+
retention: RetentionPolicy[];
|
|
54
|
+
hudFields: string[];
|
|
55
|
+
graphLabel: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const STATE_RETENTION: RetentionPolicy = { category: "state", keep: 1 };
|
|
59
|
+
const ARTIFACT_RETENTION: RetentionPolicy = { category: "artifact" };
|
|
60
|
+
const LEDGER_RETENTION: RetentionPolicy = { category: "ledger" };
|
|
61
|
+
const LOG_RETENTION: RetentionPolicy = { category: "log", maxAgeDays: 30 };
|
|
62
|
+
const REPORT_RETENTION: RetentionPolicy = { category: "report", maxAgeDays: 30 };
|
|
63
|
+
const AGENTS_RETENTION: RetentionPolicy = { category: "agents" };
|
|
64
|
+
const PRUNE_RETENTION: RetentionPolicy = { category: "prune/delete", maxAgeDays: 30 };
|
|
65
|
+
const FORCE_RETENTION: RetentionPolicy = { category: "force", maxAgeDays: 90 };
|
|
66
|
+
|
|
67
|
+
const STATE_VERBS = ["read", "write", "clear", "contract", "handoff", "doctor"] as const;
|
|
68
|
+
const PLANNED_ADMIN_VERBS = ["graph", "prune", "migrate", "force-overwrite"] as const;
|
|
69
|
+
|
|
70
|
+
const COMMON_TYPED_ARGS: TypedArgSpec[] = [
|
|
71
|
+
{ name: "input", type: "string", appliesToVerbs: ["write", "api"] },
|
|
72
|
+
{ name: "mode", type: "enum", enumValues: [...CANONICAL_GJC_WORKFLOW_SKILLS], appliesToVerbs: [...STATE_VERBS] },
|
|
73
|
+
{ name: "session-id", type: "string", appliesToVerbs: [...STATE_VERBS, "kickoff", "write-spec", "write-artifact"] },
|
|
74
|
+
{ name: "thread-id", type: "string", appliesToVerbs: ["write", "clear", "handoff"] },
|
|
75
|
+
{ name: "turn-id", type: "string", appliesToVerbs: ["write", "clear", "handoff"] },
|
|
76
|
+
{
|
|
77
|
+
name: "to",
|
|
78
|
+
type: "enum",
|
|
79
|
+
enumValues: [...CANONICAL_GJC_WORKFLOW_SKILLS],
|
|
80
|
+
required: true,
|
|
81
|
+
appliesToVerbs: ["handoff"],
|
|
82
|
+
},
|
|
83
|
+
{ name: "replace", type: "boolean", appliesToVerbs: ["write"] },
|
|
84
|
+
{ name: "force", type: "boolean", appliesToVerbs: ["write", "clear", "handoff"] },
|
|
85
|
+
{ name: "skill", type: "enum", enumValues: [...CANONICAL_GJC_WORKFLOW_SKILLS], appliesToVerbs: ["doctor"] },
|
|
86
|
+
{ name: "json", type: "boolean", appliesToVerbs: ["doctor"] },
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
function verb(name: string, surface: WorkflowVerb["surface"]): WorkflowVerb {
|
|
90
|
+
return { name, surface };
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function stateVerbs(): WorkflowVerb[] {
|
|
94
|
+
return STATE_VERBS.map(name => verb(name, "state-action"));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function positionalVerbs(names: readonly string[]): WorkflowVerb[] {
|
|
98
|
+
return names.map(name => verb(name, "command-positional"));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function flagVerbs(names: readonly string[]): WorkflowVerb[] {
|
|
102
|
+
return names.map(name => verb(name, "command-flag"));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function plannedVerbs(names: readonly string[]): WorkflowVerb[] {
|
|
106
|
+
return names.map(name => ({ ...verb(name, "state-action"), planned: true }));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function state(id: string, initialState: string, terminalStates: readonly string[]): WorkflowState {
|
|
110
|
+
const entry: WorkflowState = { id };
|
|
111
|
+
if (id === initialState) entry.initial = true;
|
|
112
|
+
if (terminalStates.includes(id)) entry.terminal = true;
|
|
113
|
+
return entry;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function manifest(input: {
|
|
117
|
+
skill: CanonicalGjcWorkflowSkill;
|
|
118
|
+
states: string[];
|
|
119
|
+
terminalStates: string[];
|
|
120
|
+
transitions: WorkflowTransition[];
|
|
121
|
+
verbs: WorkflowVerb[];
|
|
122
|
+
typedArgs?: TypedArgSpec[];
|
|
123
|
+
retention: RetentionPolicy[];
|
|
124
|
+
hudFields: string[];
|
|
125
|
+
graphLabel: string;
|
|
126
|
+
initialState?: string;
|
|
127
|
+
}): SkillManifest {
|
|
128
|
+
const staleInitialState = initialPhaseForSkill(input.skill);
|
|
129
|
+
const initialState = input.initialState ?? staleInitialState;
|
|
130
|
+
return {
|
|
131
|
+
skill: input.skill,
|
|
132
|
+
states: input.states.map(item => state(item, initialState, input.terminalStates)),
|
|
133
|
+
initialState,
|
|
134
|
+
terminalStates: input.terminalStates,
|
|
135
|
+
transitions: input.transitions,
|
|
136
|
+
verbs: input.verbs,
|
|
137
|
+
typedArgs: [...COMMON_TYPED_ARGS, ...(input.typedArgs ?? [])],
|
|
138
|
+
retention: input.retention,
|
|
139
|
+
hudFields: input.hudFields,
|
|
140
|
+
graphLabel: input.graphLabel,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export const WORKFLOW_MANIFEST: Record<CanonicalGjcWorkflowSkill, SkillManifest> = {
|
|
145
|
+
"deep-interview": manifest({
|
|
146
|
+
skill: "deep-interview",
|
|
147
|
+
states: ["interviewing", "handoff", "complete"],
|
|
148
|
+
terminalStates: ["handoff", "complete"],
|
|
149
|
+
transitions: [
|
|
150
|
+
{ from: "interviewing", to: "handoff", verb: "write-spec" },
|
|
151
|
+
{ from: "handoff", to: "complete", verb: "clear" },
|
|
152
|
+
{ from: "interviewing", to: "complete", verb: "clear" },
|
|
153
|
+
],
|
|
154
|
+
verbs: [...stateVerbs(), ...flagVerbs(["kickoff", "write-spec"]), ...plannedVerbs(PLANNED_ADMIN_VERBS)],
|
|
155
|
+
typedArgs: [
|
|
156
|
+
{ name: "quick", type: "boolean", appliesToVerbs: ["kickoff"] },
|
|
157
|
+
{ name: "standard", type: "boolean", appliesToVerbs: ["kickoff"] },
|
|
158
|
+
{ name: "deep", type: "boolean", appliesToVerbs: ["kickoff"] },
|
|
159
|
+
{ name: "threshold", type: "number", appliesToVerbs: ["kickoff"] },
|
|
160
|
+
{ name: "threshold-source", type: "string", appliesToVerbs: ["kickoff"] },
|
|
161
|
+
{ name: "stage", type: "enum", enumValues: ["final"], appliesToVerbs: ["write-spec"] },
|
|
162
|
+
{ name: "slug", type: "string", appliesToVerbs: ["write-spec"] },
|
|
163
|
+
{ name: "spec", type: "string", required: true, appliesToVerbs: ["write-spec"] },
|
|
164
|
+
{ name: "handoff", type: "enum", enumValues: ["ralplan"], appliesToVerbs: ["write-spec"] },
|
|
165
|
+
{ name: "deliberate", type: "boolean", appliesToVerbs: ["write-spec"] },
|
|
166
|
+
{ name: "json", type: "boolean", appliesToVerbs: ["write-spec"] },
|
|
167
|
+
{ name: "args", type: "string", planned: true },
|
|
168
|
+
{ name: "metadata-json", type: "string", planned: true },
|
|
169
|
+
],
|
|
170
|
+
retention: [STATE_RETENTION, ARTIFACT_RETENTION, PRUNE_RETENTION, FORCE_RETENTION],
|
|
171
|
+
hudFields: ["current_phase", "ambiguity_score", "threshold", "spec_slug", "spec_path", "topology"],
|
|
172
|
+
graphLabel: "Deep Interview",
|
|
173
|
+
}),
|
|
174
|
+
ralplan: manifest({
|
|
175
|
+
skill: "ralplan",
|
|
176
|
+
states: ["planner", "architect", "critic", "revision", "adr", "final", "handoff"],
|
|
177
|
+
terminalStates: ["final", "handoff"],
|
|
178
|
+
transitions: [
|
|
179
|
+
{ from: "planner", to: "architect", verb: "write-artifact" },
|
|
180
|
+
{ from: "architect", to: "critic", verb: "write-artifact" },
|
|
181
|
+
{ from: "critic", to: "revision", verb: "write-artifact" },
|
|
182
|
+
{ from: "revision", to: "adr", verb: "write-artifact" },
|
|
183
|
+
{ from: "adr", to: "final", verb: "write-artifact" },
|
|
184
|
+
{ from: "planner", to: "handoff", verb: "handoff" },
|
|
185
|
+
{ from: "architect", to: "handoff", verb: "handoff" },
|
|
186
|
+
{ from: "critic", to: "handoff", verb: "handoff" },
|
|
187
|
+
{ from: "revision", to: "handoff", verb: "handoff" },
|
|
188
|
+
{ from: "adr", to: "handoff", verb: "handoff" },
|
|
189
|
+
],
|
|
190
|
+
verbs: [...stateVerbs(), ...flagVerbs(["kickoff", "write-artifact"]), ...plannedVerbs(PLANNED_ADMIN_VERBS)],
|
|
191
|
+
typedArgs: [
|
|
192
|
+
{ name: "interactive", type: "boolean", appliesToVerbs: ["kickoff"] },
|
|
193
|
+
{ name: "deliberate", type: "boolean", appliesToVerbs: ["kickoff"] },
|
|
194
|
+
{ name: "architect", type: "string", appliesToVerbs: ["kickoff"] },
|
|
195
|
+
{ name: "critic", type: "string", appliesToVerbs: ["kickoff"] },
|
|
196
|
+
{ name: "json", type: "boolean", appliesToVerbs: ["kickoff", "write-artifact"] },
|
|
197
|
+
{
|
|
198
|
+
name: "stage",
|
|
199
|
+
type: "enum",
|
|
200
|
+
enumValues: ["planner", "architect", "critic", "revision", "adr", "final"],
|
|
201
|
+
appliesToVerbs: ["write-artifact"],
|
|
202
|
+
},
|
|
203
|
+
{ name: "stage_n", type: "number", appliesToVerbs: ["write-artifact"] },
|
|
204
|
+
{ name: "artifact", type: "string", required: true, appliesToVerbs: ["write-artifact"] },
|
|
205
|
+
{ name: "run-id", type: "string", appliesToVerbs: ["write-artifact"] },
|
|
206
|
+
{ name: "args", type: "string", planned: true },
|
|
207
|
+
{ name: "metadata-json", type: "string", planned: true },
|
|
208
|
+
],
|
|
209
|
+
retention: [STATE_RETENTION, ARTIFACT_RETENTION, LEDGER_RETENTION, PRUNE_RETENTION, FORCE_RETENTION],
|
|
210
|
+
hudFields: ["current_phase", "mode", "run_id", "stage", "stage_n", "plan_path"],
|
|
211
|
+
graphLabel: "Ralplan",
|
|
212
|
+
}),
|
|
213
|
+
ultragoal: manifest({
|
|
214
|
+
skill: "ultragoal",
|
|
215
|
+
states: ["goal-planning", "pending", "active", "blocked", "failed", "complete", "handoff"],
|
|
216
|
+
terminalStates: ["failed", "complete", "handoff"],
|
|
217
|
+
transitions: [
|
|
218
|
+
{ from: "goal-planning", to: "pending", verb: "create-goals" },
|
|
219
|
+
{ from: "pending", to: "active", verb: "complete-goals" },
|
|
220
|
+
{ from: "active", to: "blocked", verb: "checkpoint" },
|
|
221
|
+
{ from: "active", to: "failed", verb: "checkpoint" },
|
|
222
|
+
{ from: "active", to: "complete", verb: "checkpoint" },
|
|
223
|
+
{ from: "blocked", to: "active", verb: "checkpoint" },
|
|
224
|
+
{ from: "failed", to: "active", verb: "complete-goals" },
|
|
225
|
+
{ from: "goal-planning", to: "handoff", verb: "handoff" },
|
|
226
|
+
{ from: "pending", to: "handoff", verb: "handoff" },
|
|
227
|
+
{ from: "active", to: "handoff", verb: "handoff" },
|
|
228
|
+
{ from: "blocked", to: "handoff", verb: "handoff" },
|
|
229
|
+
],
|
|
230
|
+
verbs: [
|
|
231
|
+
...stateVerbs(),
|
|
232
|
+
...positionalVerbs([
|
|
233
|
+
"status",
|
|
234
|
+
"create",
|
|
235
|
+
"create-goals",
|
|
236
|
+
"complete-goals",
|
|
237
|
+
"checkpoint",
|
|
238
|
+
"record-review-blockers",
|
|
239
|
+
"steer",
|
|
240
|
+
]),
|
|
241
|
+
...plannedVerbs(PLANNED_ADMIN_VERBS),
|
|
242
|
+
],
|
|
243
|
+
typedArgs: [
|
|
244
|
+
{ name: "brief", type: "string", appliesToVerbs: ["create-goals"] },
|
|
245
|
+
{ name: "brief-file", type: "string", appliesToVerbs: ["create-goals"] },
|
|
246
|
+
{ name: "from-stdin", type: "boolean", appliesToVerbs: ["create-goals"] },
|
|
247
|
+
{
|
|
248
|
+
name: "gjc-goal-mode",
|
|
249
|
+
type: "enum",
|
|
250
|
+
enumValues: ["aggregate", "per-story"],
|
|
251
|
+
appliesToVerbs: ["create-goals"],
|
|
252
|
+
},
|
|
253
|
+
{ name: "retry-failed", type: "boolean", appliesToVerbs: ["complete-goals"] },
|
|
254
|
+
{ name: "goal-id", type: "string", required: true, appliesToVerbs: ["checkpoint", "record-review-blockers"] },
|
|
255
|
+
{
|
|
256
|
+
name: "status",
|
|
257
|
+
type: "enum",
|
|
258
|
+
enumValues: ["pending", "active", "complete", "failed", "blocked", "review_blocked", "superseded"],
|
|
259
|
+
required: true,
|
|
260
|
+
appliesToVerbs: ["checkpoint"],
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
name: "evidence",
|
|
264
|
+
type: "string",
|
|
265
|
+
required: true,
|
|
266
|
+
appliesToVerbs: ["checkpoint", "record-review-blockers", "steer"],
|
|
267
|
+
},
|
|
268
|
+
{ name: "gjc-goal-json", type: "string", appliesToVerbs: ["checkpoint", "record-review-blockers"] },
|
|
269
|
+
{ name: "quality-gate-json", type: "string", appliesToVerbs: ["checkpoint"] },
|
|
270
|
+
{ name: "kind", type: "enum", enumValues: ["add_subgoal"], appliesToVerbs: ["steer"] },
|
|
271
|
+
{ name: "title", type: "string", appliesToVerbs: ["record-review-blockers", "steer"] },
|
|
272
|
+
{ name: "objective", type: "string", appliesToVerbs: ["record-review-blockers", "steer"] },
|
|
273
|
+
{ name: "rationale", type: "string", appliesToVerbs: ["steer"] },
|
|
274
|
+
{
|
|
275
|
+
name: "json",
|
|
276
|
+
type: "boolean",
|
|
277
|
+
appliesToVerbs: [
|
|
278
|
+
"status",
|
|
279
|
+
"create-goals",
|
|
280
|
+
"complete-goals",
|
|
281
|
+
"checkpoint",
|
|
282
|
+
"record-review-blockers",
|
|
283
|
+
"steer",
|
|
284
|
+
],
|
|
285
|
+
},
|
|
286
|
+
{ name: "directive-json", type: "string", appliesToVerbs: ["steer"], planned: true },
|
|
287
|
+
{ name: "args", type: "string", planned: true },
|
|
288
|
+
{ name: "metadata-json", type: "string", planned: true },
|
|
289
|
+
],
|
|
290
|
+
retention: [STATE_RETENTION, ARTIFACT_RETENTION, LEDGER_RETENTION, PRUNE_RETENTION, FORCE_RETENTION],
|
|
291
|
+
hudFields: ["current_phase", "active_goal_id", "status", "counts", "ledger_path", "brief_path"],
|
|
292
|
+
graphLabel: "Ultragoal",
|
|
293
|
+
}),
|
|
294
|
+
team: manifest({
|
|
295
|
+
skill: "team",
|
|
296
|
+
states: ["starting", "running", "awaiting_integration", "complete", "failed", "cancelled", "handoff"],
|
|
297
|
+
terminalStates: ["complete", "failed", "cancelled", "handoff"],
|
|
298
|
+
transitions: [
|
|
299
|
+
{ from: "starting", to: "running", verb: "start" },
|
|
300
|
+
{ from: "starting", to: "failed", verb: "start" },
|
|
301
|
+
{ from: "running", to: "awaiting_integration", verb: "api" },
|
|
302
|
+
{ from: "running", to: "complete", verb: "shutdown" },
|
|
303
|
+
{ from: "running", to: "failed", verb: "shutdown" },
|
|
304
|
+
{ from: "running", to: "cancelled", verb: "shutdown" },
|
|
305
|
+
{ from: "awaiting_integration", to: "running", verb: "resume" },
|
|
306
|
+
{ from: "awaiting_integration", to: "complete", verb: "shutdown" },
|
|
307
|
+
{ from: "starting", to: "handoff", verb: "handoff" },
|
|
308
|
+
{ from: "running", to: "handoff", verb: "handoff" },
|
|
309
|
+
{ from: "awaiting_integration", to: "handoff", verb: "handoff" },
|
|
310
|
+
],
|
|
311
|
+
verbs: [
|
|
312
|
+
...stateVerbs(),
|
|
313
|
+
...positionalVerbs(["start", "list", "status", "monitor", "resume", "shutdown", "api"]),
|
|
314
|
+
...plannedVerbs(PLANNED_ADMIN_VERBS),
|
|
315
|
+
],
|
|
316
|
+
typedArgs: [
|
|
317
|
+
{ name: "dry-run", type: "boolean", appliesToVerbs: ["start"] },
|
|
318
|
+
{ name: "worktree", type: "string", appliesToVerbs: ["start"] },
|
|
319
|
+
{ name: "w", type: "string", appliesToVerbs: ["start"] },
|
|
320
|
+
{ name: "input", type: "string", required: true, appliesToVerbs: ["api"] },
|
|
321
|
+
{
|
|
322
|
+
name: "operation",
|
|
323
|
+
type: "enum",
|
|
324
|
+
enumValues: [
|
|
325
|
+
"send-message",
|
|
326
|
+
"broadcast",
|
|
327
|
+
"mailbox-list",
|
|
328
|
+
"mailbox-mark-delivered",
|
|
329
|
+
"mailbox-mark-notified",
|
|
330
|
+
"notification-list",
|
|
331
|
+
"notification-read",
|
|
332
|
+
"notification-replay",
|
|
333
|
+
"notification-mark-pane-attempt",
|
|
334
|
+
"worker-startup-ack",
|
|
335
|
+
"create-task",
|
|
336
|
+
"read-task",
|
|
337
|
+
"list-tasks",
|
|
338
|
+
"update-task",
|
|
339
|
+
"claim-task",
|
|
340
|
+
"transition-task-status",
|
|
341
|
+
"transition-task",
|
|
342
|
+
"release-task-claim",
|
|
343
|
+
"read-config",
|
|
344
|
+
"read-manifest",
|
|
345
|
+
"read-worker-status",
|
|
346
|
+
"read-worker-heartbeat",
|
|
347
|
+
"update-worker-heartbeat",
|
|
348
|
+
"write-worker-inbox",
|
|
349
|
+
"write-worker-identity",
|
|
350
|
+
"append-event",
|
|
351
|
+
"read-events",
|
|
352
|
+
"await-event",
|
|
353
|
+
"write-shutdown-request",
|
|
354
|
+
"read-shutdown-ack",
|
|
355
|
+
"read-monitor-snapshot",
|
|
356
|
+
"write-monitor-snapshot",
|
|
357
|
+
"read-task-approval",
|
|
358
|
+
"write-task-approval",
|
|
359
|
+
],
|
|
360
|
+
required: true,
|
|
361
|
+
appliesToVerbs: ["api"],
|
|
362
|
+
},
|
|
363
|
+
{ name: "worker-id", type: "string", appliesToVerbs: ["api"] },
|
|
364
|
+
{ name: "task-id", type: "string", appliesToVerbs: ["api"] },
|
|
365
|
+
{ name: "claim-token", type: "string", appliesToVerbs: ["api"] },
|
|
366
|
+
{
|
|
367
|
+
name: "status",
|
|
368
|
+
type: "enum",
|
|
369
|
+
enumValues: ["pending", "blocked", "in_progress", "completed", "failed"],
|
|
370
|
+
appliesToVerbs: ["api"],
|
|
371
|
+
},
|
|
372
|
+
{ name: "completion_evidence", type: "object", appliesToVerbs: ["api"] },
|
|
373
|
+
{ name: "completionEvidence", type: "object", appliesToVerbs: ["api"] },
|
|
374
|
+
{ name: "args", type: "string", planned: true },
|
|
375
|
+
{ name: "metadata-json", type: "string", planned: true },
|
|
376
|
+
],
|
|
377
|
+
retention: [
|
|
378
|
+
STATE_RETENTION,
|
|
379
|
+
ARTIFACT_RETENTION,
|
|
380
|
+
LEDGER_RETENTION,
|
|
381
|
+
LOG_RETENTION,
|
|
382
|
+
REPORT_RETENTION,
|
|
383
|
+
AGENTS_RETENTION,
|
|
384
|
+
PRUNE_RETENTION,
|
|
385
|
+
FORCE_RETENTION,
|
|
386
|
+
],
|
|
387
|
+
hudFields: ["current_phase", "team_name", "workers", "task_counts", "phase", "integration"],
|
|
388
|
+
graphLabel: "Team",
|
|
389
|
+
}),
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
export function getSkillManifest(skill: CanonicalGjcWorkflowSkill): SkillManifest {
|
|
393
|
+
return WORKFLOW_MANIFEST[skill];
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
export function isKnownWorkflowState(skill: CanonicalGjcWorkflowSkill, state: string): boolean {
|
|
397
|
+
return WORKFLOW_MANIFEST[skill].states.some(entry => entry.id === state);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
export function isValidTransition(skill: CanonicalGjcWorkflowSkill, from: string, to: string): boolean {
|
|
401
|
+
if (from === to) return true;
|
|
402
|
+
return WORKFLOW_MANIFEST[skill].transitions.some(transition => transition.from === from && transition.to === to);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
export function listVerbs(skill: CanonicalGjcWorkflowSkill): string[] {
|
|
406
|
+
return WORKFLOW_MANIFEST[skill].verbs.map(verb => verb.name);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
export function typedArgsFor(skill: CanonicalGjcWorkflowSkill, verb: string): TypedArgSpec[] {
|
|
410
|
+
return WORKFLOW_MANIFEST[skill].typedArgs.filter(
|
|
411
|
+
arg => arg.appliesToVerbs === undefined || arg.appliesToVerbs.includes(verb),
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function stableSort(value: unknown): unknown {
|
|
416
|
+
if (Array.isArray(value)) return value.map(item => stableSort(item));
|
|
417
|
+
if (value === null || typeof value !== "object") return value;
|
|
418
|
+
return Object.fromEntries(
|
|
419
|
+
Object.entries(value)
|
|
420
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
421
|
+
.map(([key, item]) => [key, stableSort(item)]),
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
export function serializeManifestProjection(): string {
|
|
426
|
+
return `${JSON.stringify(stableSort(WORKFLOW_MANIFEST), null, 2)}\n`;
|
|
427
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic recovery classifier (pure).
|
|
3
|
+
*
|
|
4
|
+
* Maps a bounded {@link Observation} + remaining retry budget to exactly one
|
|
5
|
+
* {@link RecoveryDecision}. Encodes the plan's hard data-loss invariants:
|
|
6
|
+
* - dirty deltas are NEVER `restart-clean`; they map to `restart-preserve-delta`.
|
|
7
|
+
* - unknown deltas are NEVER destructive; they map to `human-check`.
|
|
8
|
+
* - a deleted/mismatched worktree maps to `human-check` (never recreate over unknown data).
|
|
9
|
+
* `send-enter` is intentionally never emitted: it is unsupported for the gajae-code
|
|
10
|
+
* RPC adapter in v1 (no blind key injection).
|
|
11
|
+
*/
|
|
12
|
+
import type { ClassifyInput, RecoveryDecision } from "./types";
|
|
13
|
+
|
|
14
|
+
export function classifyRecovery(input: ClassifyInput): RecoveryDecision {
|
|
15
|
+
const { observation: o, retryBudget: budget } = input;
|
|
16
|
+
|
|
17
|
+
// Deleted worktree / path mismatch — never recreate over unknown data.
|
|
18
|
+
if (o.risk === "deleted-worktree") {
|
|
19
|
+
return {
|
|
20
|
+
classification: "human-check",
|
|
21
|
+
reason: "deleted-worktree-or-path-mismatch",
|
|
22
|
+
severity: "critical",
|
|
23
|
+
ownerRequired: false,
|
|
24
|
+
requiredReceiptFamily: "vanish",
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (o.ownerLive) {
|
|
29
|
+
if (o.risk === "prompt-not-accepted") {
|
|
30
|
+
if (budget.reinjectPrompt > 0) {
|
|
31
|
+
return {
|
|
32
|
+
classification: "reinject-prompt",
|
|
33
|
+
reason: "prompt-ack-without-agent-start",
|
|
34
|
+
severity: "warn",
|
|
35
|
+
ownerRequired: true,
|
|
36
|
+
requiredReceiptFamily: "prompt-acceptance",
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
classification: "human-check",
|
|
41
|
+
reason: "prompt-not-accepted-budget-exhausted",
|
|
42
|
+
severity: "critical",
|
|
43
|
+
ownerRequired: false,
|
|
44
|
+
requiredReceiptFamily: null,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
if (o.observedSignals.includes("validation-failed")) {
|
|
48
|
+
if (budget.validationRepair > 0) {
|
|
49
|
+
return {
|
|
50
|
+
classification: "continue",
|
|
51
|
+
reason: "validation-failed-repair-budget-remains",
|
|
52
|
+
severity: "warn",
|
|
53
|
+
ownerRequired: true,
|
|
54
|
+
requiredReceiptFamily: "validation",
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
classification: "human-check",
|
|
59
|
+
reason: "validation-failed-budget-exhausted",
|
|
60
|
+
severity: "critical",
|
|
61
|
+
ownerRequired: false,
|
|
62
|
+
requiredReceiptFamily: "validation",
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
classification: "continue",
|
|
67
|
+
reason: "owner-live-active",
|
|
68
|
+
severity: "info",
|
|
69
|
+
ownerRequired: true,
|
|
70
|
+
requiredReceiptFamily: null,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Owner / RPC vanished — branch on git delta. Every branch requires a `vanish` receipt.
|
|
75
|
+
switch (o.gitDelta) {
|
|
76
|
+
case "dirty":
|
|
77
|
+
if (budget.dirtyVanishPreserve > 0) {
|
|
78
|
+
return {
|
|
79
|
+
classification: "restart-preserve-delta",
|
|
80
|
+
reason: "owner-vanished-dirty-delta",
|
|
81
|
+
severity: "critical",
|
|
82
|
+
ownerRequired: true,
|
|
83
|
+
requiredReceiptFamily: "vanish",
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
classification: "fallback-codex-exec",
|
|
88
|
+
reason: "dirty-vanish-preserve-budget-exhausted",
|
|
89
|
+
severity: "critical",
|
|
90
|
+
ownerRequired: true,
|
|
91
|
+
requiredReceiptFamily: "vanish",
|
|
92
|
+
};
|
|
93
|
+
case "zero-delta":
|
|
94
|
+
if (budget.zeroDeltaVanish > 0) {
|
|
95
|
+
return {
|
|
96
|
+
classification: "restart-clean",
|
|
97
|
+
reason: "owner-vanished-zero-delta",
|
|
98
|
+
severity: "warn",
|
|
99
|
+
ownerRequired: true,
|
|
100
|
+
requiredReceiptFamily: "vanish",
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
classification: "fallback-codex-exec",
|
|
105
|
+
reason: "zero-delta-vanish-budget-exhausted",
|
|
106
|
+
severity: "critical",
|
|
107
|
+
ownerRequired: true,
|
|
108
|
+
requiredReceiptFamily: "vanish",
|
|
109
|
+
};
|
|
110
|
+
case "clean":
|
|
111
|
+
return {
|
|
112
|
+
classification: "restart-clean",
|
|
113
|
+
reason: "owner-vanished-clean",
|
|
114
|
+
severity: "warn",
|
|
115
|
+
ownerRequired: true,
|
|
116
|
+
requiredReceiptFamily: "vanish",
|
|
117
|
+
};
|
|
118
|
+
default:
|
|
119
|
+
// unknown delta — critical, never destructive.
|
|
120
|
+
return {
|
|
121
|
+
classification: "human-check",
|
|
122
|
+
reason: "owner-vanished-unknown-delta",
|
|
123
|
+
severity: "critical",
|
|
124
|
+
ownerRequired: false,
|
|
125
|
+
requiredReceiptFamily: "vanish",
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
}
|