@gajae-code/coding-agent 0.1.1 → 0.1.2
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 +4 -0
- package/dist/types/config/model-registry.d.ts +7 -0
- package/dist/types/gjc-runtime/ultragoal-guard.d.ts +26 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +44 -0
- package/dist/types/goals/tools/goal-tool.d.ts +4 -4
- package/dist/types/hooks/skill-state.d.ts +3 -0
- package/dist/types/modes/components/model-selector.d.ts +4 -4
- package/dist/types/skill-state/deep-interview-mutation-guard.d.ts +28 -0
- package/package.json +11 -7
- package/src/config/model-registry.ts +41 -0
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +30 -30
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +51 -21
- package/src/gjc-runtime/ultragoal-guard.ts +239 -0
- package/src/gjc-runtime/ultragoal-runtime.ts +318 -4
- package/src/goals/tools/goal-tool.ts +10 -4
- package/src/hooks/native-skill-hook.ts +26 -0
- package/src/hooks/skill-state.ts +59 -0
- package/src/main.ts +1 -17
- package/src/modes/components/model-selector.ts +120 -28
- package/src/modes/controllers/selector-controller.ts +16 -3
- package/src/modes/prompt-action-autocomplete.ts +40 -15
- package/src/session/agent-session.ts +31 -1
- package/src/setup/model-onboarding-guidance.ts +5 -3
- package/src/skill-state/deep-interview-mutation-guard.ts +303 -0
- package/src/slash-commands/builtin-registry.ts +130 -11
- package/src/tools/ask.ts +55 -17
- package/src/tools/ast-edit.ts +7 -0
- package/src/tools/bash.ts +2 -1
- package/src/tools/gh.ts +37 -9
- package/src/tools/path-utils.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,13 @@ export interface ModelRoleInfo {
|
|
|
16
16
|
}
|
|
17
17
|
export declare const MODEL_ROLES: Record<ModelRole, ModelRoleInfo>;
|
|
18
18
|
export declare const MODEL_ROLE_IDS: ModelRole[];
|
|
19
|
+
export type GjcModelAssignmentTargetId = "default" | "executor" | "architect" | "planner" | "critic";
|
|
20
|
+
export interface GjcModelAssignmentTargetInfo extends ModelRoleInfo {
|
|
21
|
+
id: GjcModelAssignmentTargetId;
|
|
22
|
+
settingsPath: "modelRoles" | "task.agentModelOverrides";
|
|
23
|
+
}
|
|
24
|
+
export declare const GJC_MODEL_ASSIGNMENT_TARGET_IDS: GjcModelAssignmentTargetId[];
|
|
25
|
+
export declare const GJC_MODEL_ASSIGNMENT_TARGETS: Record<GjcModelAssignmentTargetId, GjcModelAssignmentTargetInfo>;
|
|
19
26
|
/** Alias for ModelRoleInfo - used for both built-in and custom roles */
|
|
20
27
|
export type RoleInfo = ModelRoleInfo;
|
|
21
28
|
/**
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type UltragoalGoal, type UltragoalLedgerEvent, type UltragoalPlan, type UltragoalReceiptKind } from "./ultragoal-runtime";
|
|
2
|
+
export type UltragoalGuardState = "inactive" | "unrelated_goal" | "active_verified_complete" | "active_missing_receipt" | "active_stale_receipt" | "active_missing_final_receipt" | "active_dirty_quality_gate" | "active_review_blocked_unrecorded" | "active_review_blocked_recorded" | "unreadable_fail_closed";
|
|
3
|
+
export interface UltragoalGuardDiagnostic {
|
|
4
|
+
state: UltragoalGuardState;
|
|
5
|
+
message: string;
|
|
6
|
+
goalId?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface CurrentGoalLike {
|
|
9
|
+
objective: string;
|
|
10
|
+
status?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function validateCompletionReceipt(input: {
|
|
13
|
+
plan: UltragoalPlan;
|
|
14
|
+
ledger: readonly UltragoalLedgerEvent[];
|
|
15
|
+
goal: UltragoalGoal;
|
|
16
|
+
receiptKind: UltragoalReceiptKind;
|
|
17
|
+
}): UltragoalGuardDiagnostic;
|
|
18
|
+
export declare function readUltragoalVerificationState(input: {
|
|
19
|
+
cwd: string;
|
|
20
|
+
currentGoal?: CurrentGoalLike | null;
|
|
21
|
+
}): Promise<UltragoalGuardDiagnostic>;
|
|
22
|
+
export declare function assertCanCompleteCurrentGoal(input: {
|
|
23
|
+
cwd: string;
|
|
24
|
+
currentGoal?: CurrentGoalLike | null;
|
|
25
|
+
}): Promise<void>;
|
|
26
|
+
export declare function isUltragoalBypassPrompt(prompt: string): boolean;
|
|
@@ -11,6 +11,7 @@ export interface UltragoalGoal {
|
|
|
11
11
|
completedAt?: string;
|
|
12
12
|
evidence?: string;
|
|
13
13
|
steering?: Record<string, unknown>;
|
|
14
|
+
completionVerification?: UltragoalCompletionVerification;
|
|
14
15
|
}
|
|
15
16
|
export interface UltragoalPlan {
|
|
16
17
|
version: 1;
|
|
@@ -22,6 +23,33 @@ export interface UltragoalPlan {
|
|
|
22
23
|
createdAt: string;
|
|
23
24
|
updatedAt: string;
|
|
24
25
|
}
|
|
26
|
+
export type UltragoalReceiptKind = "per-goal" | "final-aggregate";
|
|
27
|
+
export interface UltragoalCompletionVerification {
|
|
28
|
+
schemaVersion: 1;
|
|
29
|
+
receiptId: string;
|
|
30
|
+
verifiedAt: string;
|
|
31
|
+
goalId: string;
|
|
32
|
+
receiptKind: UltragoalReceiptKind;
|
|
33
|
+
goalStatusBeforeCheckpoint: UltragoalGoalStatus;
|
|
34
|
+
gjcGoalMode: UltragoalGjcGoalMode;
|
|
35
|
+
gjcObjective: string;
|
|
36
|
+
qualityGateHash: string;
|
|
37
|
+
planGeneration: string;
|
|
38
|
+
basis: {
|
|
39
|
+
planHashBeforeCheckpoint: string;
|
|
40
|
+
latestRelevantLedgerEventIdBeforeCheckpoint: string | null;
|
|
41
|
+
goalUpdatedAtBeforeCheckpoint: string;
|
|
42
|
+
relevantGoalIdsBeforeCheckpoint: string[];
|
|
43
|
+
requiredGoalSetHashBeforeCheckpoint: string;
|
|
44
|
+
};
|
|
45
|
+
checkpointLedgerEventId: string;
|
|
46
|
+
}
|
|
47
|
+
export interface UltragoalLedgerEvent extends JsonObject {
|
|
48
|
+
eventId?: string;
|
|
49
|
+
event?: string;
|
|
50
|
+
goalId?: string;
|
|
51
|
+
timestamp?: string;
|
|
52
|
+
}
|
|
25
53
|
export interface UltragoalPaths {
|
|
26
54
|
dir: string;
|
|
27
55
|
briefPath: string;
|
|
@@ -43,7 +71,12 @@ export interface UltragoalCommandResult {
|
|
|
43
71
|
stderr?: string;
|
|
44
72
|
createdPlan?: boolean;
|
|
45
73
|
}
|
|
74
|
+
interface JsonObject {
|
|
75
|
+
[key: string]: unknown;
|
|
76
|
+
}
|
|
77
|
+
export declare function hashStructuredValue(value: unknown): string;
|
|
46
78
|
export declare function getUltragoalPaths(cwd: string): UltragoalPaths;
|
|
79
|
+
export declare function readUltragoalLedger(cwd: string): Promise<UltragoalLedgerEvent[]>;
|
|
47
80
|
export declare function readUltragoalPlan(cwd: string): Promise<UltragoalPlan | null>;
|
|
48
81
|
export declare function getUltragoalStatus(cwd: string): Promise<UltragoalStatusSummary>;
|
|
49
82
|
export declare function createUltragoalPlan(input: {
|
|
@@ -59,6 +92,16 @@ export declare function startNextUltragoalGoal(input: {
|
|
|
59
92
|
goal?: UltragoalGoal;
|
|
60
93
|
allComplete: boolean;
|
|
61
94
|
}>;
|
|
95
|
+
export declare function computeUltragoalPlanGeneration(input: {
|
|
96
|
+
plan: UltragoalPlan;
|
|
97
|
+
ledger: readonly UltragoalLedgerEvent[];
|
|
98
|
+
goal: UltragoalGoal;
|
|
99
|
+
receiptKind: UltragoalReceiptKind;
|
|
100
|
+
beforeStatus: UltragoalGoalStatus;
|
|
101
|
+
excludeEventId?: string;
|
|
102
|
+
}): UltragoalCompletionVerification["basis"] & {
|
|
103
|
+
planGeneration: string;
|
|
104
|
+
};
|
|
62
105
|
export declare function checkpointUltragoalGoal(input: {
|
|
63
106
|
cwd: string;
|
|
64
107
|
goalId: string;
|
|
@@ -83,3 +126,4 @@ export declare function recordUltragoalReviewBlockers(input: {
|
|
|
83
126
|
gjcGoalJson?: string;
|
|
84
127
|
}): Promise<UltragoalPlan>;
|
|
85
128
|
export declare function runNativeUltragoalCommand(args: string[], cwd?: string): Promise<UltragoalCommandResult>;
|
|
129
|
+
export {};
|
|
@@ -43,7 +43,7 @@ export declare class GoalTool implements AgentTool<typeof goalSchema, GoalToolDe
|
|
|
43
43
|
#private;
|
|
44
44
|
readonly name = "goal";
|
|
45
45
|
readonly label = "Goal";
|
|
46
|
-
readonly loadMode
|
|
46
|
+
readonly loadMode: "essential";
|
|
47
47
|
readonly description: string;
|
|
48
48
|
readonly parameters: z.ZodObject<{
|
|
49
49
|
op: z.ZodEnum<{
|
|
@@ -65,7 +65,7 @@ export declare class GetGoalTool implements AgentTool<typeof getGoalSchema, Goal
|
|
|
65
65
|
#private;
|
|
66
66
|
readonly name = "get_goal";
|
|
67
67
|
readonly label = "Get Goal";
|
|
68
|
-
readonly loadMode
|
|
68
|
+
readonly loadMode: "essential";
|
|
69
69
|
readonly description: string;
|
|
70
70
|
readonly parameters: z.ZodObject<{}, z.core.$strip>;
|
|
71
71
|
readonly strict = true;
|
|
@@ -78,7 +78,7 @@ export declare class CreateGoalTool implements AgentTool<typeof createGoalSchema
|
|
|
78
78
|
#private;
|
|
79
79
|
readonly name = "create_goal";
|
|
80
80
|
readonly label = "Create Goal";
|
|
81
|
-
readonly loadMode
|
|
81
|
+
readonly loadMode: "essential";
|
|
82
82
|
readonly description: string;
|
|
83
83
|
readonly parameters: z.ZodObject<{
|
|
84
84
|
objective: z.ZodString;
|
|
@@ -94,7 +94,7 @@ export declare class UpdateGoalTool implements AgentTool<typeof updateGoalSchema
|
|
|
94
94
|
#private;
|
|
95
95
|
readonly name = "update_goal";
|
|
96
96
|
readonly label = "Update Goal";
|
|
97
|
-
readonly loadMode
|
|
97
|
+
readonly loadMode: "essential";
|
|
98
98
|
readonly description: string;
|
|
99
99
|
readonly parameters: z.ZodObject<{
|
|
100
100
|
status: z.ZodEnum<{
|
|
@@ -63,12 +63,15 @@ export interface StopHookInput {
|
|
|
63
63
|
sessionId?: string;
|
|
64
64
|
threadId?: string;
|
|
65
65
|
stateDir?: string;
|
|
66
|
+
sessionFile?: string;
|
|
66
67
|
}
|
|
67
68
|
export interface UserPromptSubmitStateInput {
|
|
68
69
|
cwd: string;
|
|
69
70
|
sessionId?: string;
|
|
70
71
|
threadId?: string;
|
|
71
72
|
stateDir?: string;
|
|
73
|
+
prompt?: string;
|
|
74
|
+
sessionFile?: string;
|
|
72
75
|
}
|
|
73
76
|
export declare function detectSkillKeywords(text: string): SkillKeywordMatch[];
|
|
74
77
|
export declare function detectPrimarySkillKeyword(text: string): SkillKeywordMatch | null;
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { ThinkingLevel } from "@gajae-code/agent-core";
|
|
2
2
|
import { type Model } from "@gajae-code/ai";
|
|
3
3
|
import { Container, Input, type TUI } from "@gajae-code/tui";
|
|
4
|
-
import type { ModelRegistry } from "../../config/model-registry";
|
|
4
|
+
import type { GjcModelAssignmentTargetId, ModelRegistry } from "../../config/model-registry";
|
|
5
5
|
import type { Settings } from "../../config/settings";
|
|
6
6
|
interface ScopedModelItem {
|
|
7
7
|
model: Model;
|
|
8
|
-
thinkingLevel?:
|
|
8
|
+
thinkingLevel?: ThinkingLevel;
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
11
|
* Component that renders a canonical model selector with provider tabs.
|
|
12
12
|
* - Tab/Arrow Left/Right: Switch between provider tabs
|
|
13
13
|
* - Arrow Up/Down: Navigate model list
|
|
14
|
-
* - Enter:
|
|
14
|
+
* - Enter: Open assignment actions for default plus GJC role-agent models
|
|
15
15
|
* - Escape: Close selector
|
|
16
16
|
*/
|
|
17
17
|
export declare class ModelSelectorComponent extends Container {
|
|
18
18
|
#private;
|
|
19
|
-
constructor(tui: TUI, _currentModel: Model | undefined, settings: Settings, modelRegistry: ModelRegistry, scopedModels: ReadonlyArray<ScopedModelItem>, onSelect: (model: Model, role:
|
|
19
|
+
constructor(tui: TUI, _currentModel: Model | undefined, settings: Settings, modelRegistry: ModelRegistry, scopedModels: ReadonlyArray<ScopedModelItem>, onSelect: (model: Model, role: GjcModelAssignmentTargetId | null, thinkingLevel?: ThinkingLevel, selector?: string) => void, onCancel: () => void, options?: {
|
|
20
20
|
temporaryOnly?: boolean;
|
|
21
21
|
initialSearchInput?: string;
|
|
22
22
|
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AgentTool } from "@gajae-code/agent-core";
|
|
2
|
+
export declare const DEEP_INTERVIEW_MUTATION_BLOCK_MESSAGE = "Deep-interview is active; either continue interviewing with `ask`, or write/finalize the pending spec under `.gjc/specs/` / update state under `.gjc/state/`. Do not edit product code until explicit execution approval.";
|
|
3
|
+
type ToolWithEditMode = AgentTool & {
|
|
4
|
+
mode?: unknown;
|
|
5
|
+
customWireName?: unknown;
|
|
6
|
+
};
|
|
7
|
+
export interface DeepInterviewMutationGuardInput {
|
|
8
|
+
cwd: string;
|
|
9
|
+
sessionId?: string;
|
|
10
|
+
threadId?: string;
|
|
11
|
+
tool: ToolWithEditMode;
|
|
12
|
+
args: unknown;
|
|
13
|
+
}
|
|
14
|
+
export interface DeepInterviewMutationDecision {
|
|
15
|
+
blocked: boolean;
|
|
16
|
+
message?: string;
|
|
17
|
+
targets: string[];
|
|
18
|
+
reason?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function assertDeepInterviewMutationRawPathsAllowed(input: {
|
|
21
|
+
cwd: string;
|
|
22
|
+
sessionId?: string;
|
|
23
|
+
threadId?: string;
|
|
24
|
+
rawPaths: string[];
|
|
25
|
+
}): Promise<void>;
|
|
26
|
+
export declare function getDeepInterviewMutationDecision(input: DeepInterviewMutationGuardInput): Promise<DeepInterviewMutationDecision>;
|
|
27
|
+
export declare function assertDeepInterviewMutationAllowed(input: DeepInterviewMutationGuardInput): Promise<void>;
|
|
28
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@gajae-code/coding-agent",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.2",
|
|
5
5
|
"description": "Gajae Code CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://gajae-code.dev",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -48,12 +48,12 @@
|
|
|
48
48
|
"@agentclientprotocol/sdk": "0.21.0",
|
|
49
49
|
"@babel/parser": "^7.29.3",
|
|
50
50
|
"@mozilla/readability": "^0.6.0",
|
|
51
|
-
"@gajae-code/stats": "0.1.
|
|
52
|
-
"@gajae-code/agent-core": "0.1.
|
|
53
|
-
"@gajae-code/ai": "0.1.
|
|
54
|
-
"@gajae-code/natives": "0.1.
|
|
55
|
-
"@gajae-code/tui": "0.1.
|
|
56
|
-
"@gajae-code/utils": "0.1.
|
|
51
|
+
"@gajae-code/stats": "0.1.2",
|
|
52
|
+
"@gajae-code/agent-core": "0.1.2",
|
|
53
|
+
"@gajae-code/ai": "0.1.2",
|
|
54
|
+
"@gajae-code/natives": "0.1.2",
|
|
55
|
+
"@gajae-code/tui": "0.1.2",
|
|
56
|
+
"@gajae-code/utils": "0.1.2",
|
|
57
57
|
"@puppeteer/browsers": "^2.13.0",
|
|
58
58
|
"@types/turndown": "5.0.6",
|
|
59
59
|
"@xterm/headless": "^6.0.0",
|
|
@@ -84,6 +84,10 @@
|
|
|
84
84
|
"dist/types"
|
|
85
85
|
],
|
|
86
86
|
"exports": {
|
|
87
|
+
"./cli": {
|
|
88
|
+
"types": "./dist/types/cli.d.ts",
|
|
89
|
+
"import": "./src/cli.ts"
|
|
90
|
+
},
|
|
87
91
|
".": {
|
|
88
92
|
"types": "./dist/types/index.d.ts",
|
|
89
93
|
"import": "./src/index.ts"
|
|
@@ -80,6 +80,47 @@ export const MODEL_ROLES: Record<ModelRole, ModelRoleInfo> = {
|
|
|
80
80
|
|
|
81
81
|
export const MODEL_ROLE_IDS: ModelRole[] = ["default", "smol", "slow", "vision", "plan", "designer", "commit", "task"];
|
|
82
82
|
|
|
83
|
+
export type GjcModelAssignmentTargetId = "default" | "executor" | "architect" | "planner" | "critic";
|
|
84
|
+
|
|
85
|
+
export interface GjcModelAssignmentTargetInfo extends ModelRoleInfo {
|
|
86
|
+
id: GjcModelAssignmentTargetId;
|
|
87
|
+
settingsPath: "modelRoles" | "task.agentModelOverrides";
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export const GJC_MODEL_ASSIGNMENT_TARGET_IDS: GjcModelAssignmentTargetId[] = [
|
|
91
|
+
"default",
|
|
92
|
+
"executor",
|
|
93
|
+
"architect",
|
|
94
|
+
"planner",
|
|
95
|
+
"critic",
|
|
96
|
+
];
|
|
97
|
+
|
|
98
|
+
export const GJC_MODEL_ASSIGNMENT_TARGETS: Record<GjcModelAssignmentTargetId, GjcModelAssignmentTargetInfo> = {
|
|
99
|
+
default: { id: "default", tag: "DEFAULT", name: "Default", color: "success", settingsPath: "modelRoles" },
|
|
100
|
+
executor: {
|
|
101
|
+
id: "executor",
|
|
102
|
+
tag: "EXECUTOR",
|
|
103
|
+
name: "Executor",
|
|
104
|
+
color: "accent",
|
|
105
|
+
settingsPath: "task.agentModelOverrides",
|
|
106
|
+
},
|
|
107
|
+
architect: {
|
|
108
|
+
id: "architect",
|
|
109
|
+
tag: "ARCHITECT",
|
|
110
|
+
name: "Architect",
|
|
111
|
+
color: "muted",
|
|
112
|
+
settingsPath: "task.agentModelOverrides",
|
|
113
|
+
},
|
|
114
|
+
planner: {
|
|
115
|
+
id: "planner",
|
|
116
|
+
tag: "PLANNER",
|
|
117
|
+
name: "Planner",
|
|
118
|
+
color: "warning",
|
|
119
|
+
settingsPath: "task.agentModelOverrides",
|
|
120
|
+
},
|
|
121
|
+
critic: { id: "critic", tag: "CRITIC", name: "Critic", color: "error", settingsPath: "task.agentModelOverrides" },
|
|
122
|
+
};
|
|
123
|
+
|
|
83
124
|
/** Alias for ModelRoleInfo - used for both built-in and custom roles */
|
|
84
125
|
export type RoleInfo = ModelRoleInfo;
|
|
85
126
|
|
|
@@ -60,11 +60,11 @@ Inspired by the [Ouroboros project](https://github.com/Q00/ouroboros) which demo
|
|
|
60
60
|
|
|
61
61
|
## Native Plugin Invocation Guard (Issue #3030)
|
|
62
62
|
|
|
63
|
-
If this raw bundled skill is loaded by GJC's native skill loader through `/
|
|
63
|
+
If this raw bundled skill is loaded by GJC's native skill loader through `/skill:deep-interview` or `gjc deep-interview`, do not treat that path as permission to skip rendered GJC setup. The user-facing invocation is `/skill:deep-interview`; do not recommend or advertise deprecated aliases as the deep-interview entrypoint. Regardless of invocation path, Phase 0 below remains blocking and must resolve `gjc.deepInterview.ambiguityThreshold` from settings before any announcement, state write, question, or ambiguity score.
|
|
64
64
|
|
|
65
65
|
## Phase 0: Resolve Ambiguity Threshold (blocking prerequisite)
|
|
66
66
|
|
|
67
|
-
Complete this phase before Phase 1, before brownfield exploration, before
|
|
67
|
+
Complete this phase before Phase 1, before brownfield exploration, before GJC state persistence, before Round 0, and before any ambiguity scoring. Do not continue if the resolved threshold and source are unknown.
|
|
68
68
|
|
|
69
69
|
1. **Read threshold settings in precedence order**:
|
|
70
70
|
- User settings: `[$GJC_CONFIG_DIR|~/.gjc]/settings.json`
|
|
@@ -81,7 +81,7 @@ Deep Interview threshold: <resolvedThresholdPercent> (source: <resolvedThreshold
|
|
|
81
81
|
|
|
82
82
|
4. **Carry threshold source forward mechanically**:
|
|
83
83
|
- Substitute `<resolvedThreshold>`, `<resolvedThresholdPercent>`, and `<resolvedThresholdSource>` throughout the remaining instructions before continuing.
|
|
84
|
-
- Include `threshold_source` in the first `
|
|
84
|
+
- Include `threshold_source` in the first `gjc state write` payload (or `.gjc/state/` state file) and preserve it on later state updates.
|
|
85
85
|
- Include both threshold and source in the final spec metadata.
|
|
86
86
|
|
|
87
87
|
## Phase 1: Initialize
|
|
@@ -106,9 +106,9 @@ Deep Interview threshold: <resolvedThresholdPercent> (source: <resolvedThreshold
|
|
|
106
106
|
- Wait until the summary exists before ambiguity scoring, weakest-dimension selection, brownfield exploration prompts, or any bridge to `ralplan`, `execution`, `execution`, or `team`.
|
|
107
107
|
3.7. **Artifact path discipline**:
|
|
108
108
|
- Final specs MUST be written to `.gjc/specs/deep-interview-{slug}.md` exactly.
|
|
109
|
-
- Ephemeral interview artifacts (scoring scratchpads, prompt-safe summaries, transient queues, resume metadata) belong in `.gjc/state/` or
|
|
109
|
+
- Ephemeral interview artifacts (scoring scratchpads, prompt-safe summaries, transient queues, resume metadata) belong in `.gjc/state/` or via `gjc state write` when available, never in the repo root or arbitrary working files.
|
|
110
110
|
|
|
111
|
-
4. **Initialize state** via `
|
|
111
|
+
4. **Initialize state** via `gjc state write` when available, otherwise by writing the deep-interview state under `.gjc/state/`:
|
|
112
112
|
|
|
113
113
|
```json
|
|
114
114
|
{
|
|
@@ -226,7 +226,7 @@ Build the question generation prompt with:
|
|
|
226
226
|
- Brownfield codebase context (if applicable), summarized to cited paths/symbols/patterns instead of raw dumps
|
|
227
227
|
- Locked topology from Round 0, including active components, deferred components, prior per-component scores, and `last_targeted_component_id`
|
|
228
228
|
|
|
229
|
-
If any prompt input is too large, summarize it first and then continue from the summary. Do not ask the next `
|
|
229
|
+
If any prompt input is too large, summarize it first and then continue from the summary. Do not ask the next the `ask` tool, score ambiguity, or hand off to execution from an over-budget raw transcript.
|
|
230
230
|
|
|
231
231
|
**Question targeting strategy:**
|
|
232
232
|
- Identify the active component + dimension pair with the LOWEST clarity score across the locked topology
|
|
@@ -247,7 +247,7 @@ If any prompt input is too large, summarize it first and then continue from the
|
|
|
247
247
|
|
|
248
248
|
### Step 2b: Ask the Question
|
|
249
249
|
|
|
250
|
-
Use `
|
|
250
|
+
Use the `ask` tool with the generated question. Present it clearly with the current ambiguity context:
|
|
251
251
|
|
|
252
252
|
```
|
|
253
253
|
Round {n} | Component: {target_component_name} | Targeting: {weakest_dimension} | Why now: {one_sentence_targeting_rationale} | Ambiguity: {score}%
|
|
@@ -354,7 +354,7 @@ Round {n} complete.
|
|
|
354
354
|
|
|
355
355
|
### Step 2e: Update State
|
|
356
356
|
|
|
357
|
-
Update interview state with the new round, global scores, per-component `topology.components[].clarity_scores`, `topology.components[].weakest_dimension`, ontology snapshot, and `topology.last_targeted_component_id` via `
|
|
357
|
+
Update interview state with the new round, global scores, per-component `topology.components[].clarity_scores`, `topology.components[].weakest_dimension`, ontology snapshot, and `topology.last_targeted_component_id` via `gjc state write`.
|
|
358
358
|
|
|
359
359
|
### Step 2f: Check Soft Limits
|
|
360
360
|
|
|
@@ -388,7 +388,7 @@ When ambiguity ≤ threshold (or hard cap / early exit):
|
|
|
388
388
|
1. **Generate the specification** using opus model with the prompt-safe transcript. If the full interview transcript or initial context is too large, include the summary plus all concrete decisions, acceptance criteria, unresolved gaps, and ontology snapshots; never overflow the prompt with raw oversized context.
|
|
389
389
|
2. **Write to file**: `.gjc/specs/deep-interview-{slug}.md`
|
|
390
390
|
- Always use this exact final spec path. Do not write temporary working files to the repo root or other ad hoc paths; repos may allowlist `.gjc/` for planning artifacts while protecting product branches.
|
|
391
|
-
- For ephemeral artifacts during interview rounds (for example scoring intermediate results, prompt-safe summaries, question queues, or resume metadata), use `.gjc/state/` or in-memory state via `
|
|
391
|
+
- For ephemeral artifacts during interview rounds (for example scoring intermediate results, prompt-safe summaries, question queues, or resume metadata), use `.gjc/state/` or in-memory state via `gjc state write`.
|
|
392
392
|
- Persist the final `spec_path` in state when available so downstream skills and resumed sessions can pass the artifact path explicitly.
|
|
393
393
|
|
|
394
394
|
Spec structure:
|
|
@@ -483,9 +483,9 @@ Spec structure:
|
|
|
483
483
|
|
|
484
484
|
## Phase 5: Execution Bridge
|
|
485
485
|
|
|
486
|
-
**Research workflow override:** if `--research-setup` is active, skip the standard execution options below
|
|
486
|
+
**Research workflow override:** if `--research-setup` is active, skip the standard execution options below and write a pending-approval spec that names research setup as an unresolved follow-up. Do not invoke deprecated research workflow shims.
|
|
487
487
|
|
|
488
|
-
After the spec is written, mark it `pending approval` and present execution options via `
|
|
488
|
+
After the spec is written, mark it `pending approval` and present execution options via the `ask` tool. Until the user selects an execution option, the deep-interview module MUST NOT run mutation-oriented shell commands, edit source files, commit, push, open PRs, invoke execution skills, or delegate implementation tasks:
|
|
489
489
|
|
|
490
490
|
**Question:** "Your spec is ready (ambiguity: {score}%). How would you like to proceed?"
|
|
491
491
|
|
|
@@ -493,26 +493,26 @@ After the spec is written, mark it `pending approval` and present execution opti
|
|
|
493
493
|
|
|
494
494
|
1. **Refine with ralplan consensus (Recommended)**
|
|
495
495
|
- Description: "Consensus-refine this spec with Planner/Architect/Critic, then stop for explicit execution approval. Maximum quality."
|
|
496
|
-
- Action: Only after the user selects this option, invoke
|
|
496
|
+
- Action: Only after the user selects this option, invoke `/skill:ralplan` or `gjc ralplan --consensus --direct` with the spec file path as context. The `--direct` flag skips the ralplan skill's interview phase (the deep interview already gathered requirements), while `--consensus` triggers the Planner/Architect/Critic loop. When consensus completes and produces a plan in `.gjc/plans/`, stop with that plan marked `pending approval`; do not automatically invoke execution or any other execution skill.
|
|
497
497
|
- Pipeline: `deep-interview spec → explicit approval to refine → ralplan --consensus --direct → pending approval → separate execution approval`
|
|
498
498
|
|
|
499
499
|
2. **Execute with team**
|
|
500
500
|
- Description: "Full autonomous pipeline — planning, parallel implementation, QA, validation. Faster but without consensus refinement."
|
|
501
|
-
- Action: Invoke
|
|
501
|
+
- Action: Invoke `/skill:team` or `gjc team` with the spec file path as context only after the user explicitly selects this execution option. The spec replaces team planning input.
|
|
502
502
|
|
|
503
503
|
3. **Execute with team**
|
|
504
504
|
- Description: "Persistence loop with architect verification — keeps working until all acceptance criteria pass"
|
|
505
|
-
- Action: Invoke
|
|
505
|
+
- Action: Invoke `/skill:team` or `gjc team` with the spec file path as the task definition.
|
|
506
506
|
|
|
507
507
|
4. **Execute with team**
|
|
508
508
|
- Description: "N coordinated parallel agents — fastest execution for large specs"
|
|
509
|
-
- Action: Invoke
|
|
509
|
+
- Action: Invoke `/skill:team` or `gjc team` with the spec file path as the shared plan.
|
|
510
510
|
|
|
511
511
|
5. **Refine further**
|
|
512
512
|
- Description: "Continue interviewing to improve clarity (current: {score}%)"
|
|
513
513
|
- Action: Return to Phase 2 interview loop.
|
|
514
514
|
|
|
515
|
-
**IMPORTANT:** On explicit execution selection, **MUST**
|
|
515
|
+
**IMPORTANT:** On explicit execution selection, **MUST** use the chosen public GJC workflow entrypoint (`/skill:ralplan`, `/skill:team`, `gjc ralplan`, or `gjc team`). Do NOT implement directly. The deep-interview agent is a requirements agent, not an execution agent. If oversized initial context was summarized, pass the spec and prompt-safe summary forward, not the raw oversized source material. Without explicit execution selection, stop with the spec marked `pending approval`.
|
|
516
516
|
|
|
517
517
|
### Approval-Gated Refinement Path (Recommended)
|
|
518
518
|
|
|
@@ -541,14 +541,14 @@ Skipping any stage is possible but reduces quality assurance:
|
|
|
541
541
|
</Steps>
|
|
542
542
|
|
|
543
543
|
<Tool_Usage>
|
|
544
|
-
- Use `
|
|
545
|
-
- Preserve the
|
|
546
|
-
- Use `
|
|
544
|
+
- Use the `ask` tool for each interview question — provides clickable UI with contextual options
|
|
545
|
+
- Preserve the GJC `ask` tool path for native interaction; do not introduce parallel structured-question transport into this skill
|
|
546
|
+
- Use `read/search/find exploration or a bounded read-only planner/architect subagent` for brownfield codebase exploration (run BEFORE asking user about codebase)
|
|
547
547
|
- Use opus model (temperature 0.1) for ambiguity scoring — consistency is critical
|
|
548
548
|
- Round 0 topology confirmation happens before ambiguity scoring; Phase 2 scoring must honor locked topology and rotate targeting across active components when more than one is present
|
|
549
|
-
- Use `
|
|
550
|
-
- Use `
|
|
551
|
-
- Use
|
|
549
|
+
- Use `gjc state write` / `gjc state read` for interview state persistence; the initial and subsequent deep-interview state payloads must include `threshold_source` alongside `threshold`
|
|
550
|
+
- Use the `write` tool to save the final spec to `.gjc/specs/deep-interview-{slug}.md` exactly; use `.gjc/state/` or `gjc state write` for ephemeral artifacts
|
|
551
|
+
- Use public GJC workflow entrypoints to bridge to ralplan/team only after explicit execution approval — never implement directly
|
|
552
552
|
- Challenge agent modes are prompt injections, not separate agent spawns
|
|
553
553
|
</Tool_Usage>
|
|
554
554
|
|
|
@@ -671,12 +671,12 @@ Why bad: 45% ambiguity means nearly half the requirements are unclear. The mathe
|
|
|
671
671
|
- [ ] Ambiguity score displayed after every round
|
|
672
672
|
- [ ] Every round explicitly names the weakest dimension and why it is the next target
|
|
673
673
|
- [ ] Challenge agents activated at correct thresholds (round 4, 6, 8)
|
|
674
|
-
- [ ] Spec file written to `.gjc/specs/deep-interview-{slug}.md` exactly; ephemeral artifacts stayed under `.gjc/state/` or `
|
|
674
|
+
- [ ] Spec file written to `.gjc/specs/deep-interview-{slug}.md` exactly; ephemeral artifacts stayed under `.gjc/state/` or `gjc state write`
|
|
675
675
|
- [ ] Spec includes: topology, goal, constraints, acceptance criteria, clarity breakdown, transcript
|
|
676
|
-
- [ ] Execution bridge presented via
|
|
677
|
-
- [ ] Selected execution mode invoked via
|
|
676
|
+
- [ ] Execution bridge presented via the `ask` tool
|
|
677
|
+
- [ ] Selected execution mode invoked via public GJC workflow entrypoint only after explicit execution approval (never direct implementation)
|
|
678
678
|
- [ ] If 3-stage pipeline selected: ralplan --consensus --direct invoked, then stopped with the consensus plan marked `pending approval` until the user explicitly approves execution
|
|
679
|
-
- [ ] State cleaned up after
|
|
679
|
+
- [ ] State cleaned up after approved workflow handoff
|
|
680
680
|
- [ ] Brownfield confirmation questions cite repo evidence (file/path/pattern) before asking the user to decide
|
|
681
681
|
- [ ] Scope-fuzzy tasks can trigger ontology-style questioning to stabilize the core entity before feature elaboration
|
|
682
682
|
- [ ] Round 0 topology gate completed before ambiguity scoring and persisted `topology.confirmed_at`
|
|
@@ -712,17 +712,17 @@ Optional settings in `.gjc/settings.json`:
|
|
|
712
712
|
|
|
713
713
|
If interrupted, run `/skill:deep-interview` again. The skill reads state from `.gjc/state/deep-interview-state.json` and resumes from the last completed round.
|
|
714
714
|
|
|
715
|
-
## Integration with
|
|
715
|
+
## Integration with staged team routing
|
|
716
716
|
|
|
717
717
|
When team receives a vague input (no file paths, function names, or concrete anchors), it can redirect to deep-interview:
|
|
718
718
|
|
|
719
719
|
```
|
|
720
720
|
User: "team build me a thing"
|
|
721
|
-
|
|
721
|
+
Team routing: "Your request is quite open-ended. Would you like to run a deep interview first to clarify requirements?"
|
|
722
722
|
[Yes, interview first] [No, expand directly]
|
|
723
723
|
```
|
|
724
724
|
|
|
725
|
-
If the user chooses interview,
|
|
725
|
+
If the user chooses interview, team routing invokes `/skill:deep-interview`. When the interview completes and the user selects "Execute with team", the spec becomes Phase 0 output and team proceeds from the approved spec.
|
|
726
726
|
|
|
727
727
|
## Approval-Gated Pipeline: deep-interview → ralplan → pending approval
|
|
728
728
|
|
|
@@ -753,7 +753,7 @@ The recommended refinement path chains clarity and feasibility gates, then stops
|
|
|
753
753
|
|
|
754
754
|
## Integration with Ralplan Gate
|
|
755
755
|
|
|
756
|
-
The ralplan pre-
|
|
756
|
+
The ralplan pre-approval gate already redirects vague prompts to planning. Deep interview can serve as an alternative redirect target for prompts that are too vague even for ralplan:
|
|
757
757
|
|
|
758
758
|
```
|
|
759
759
|
Vague prompt → ralplan gate → deep-interview (if extremely vague) → ralplan (with clear spec) → pending approval → explicitly approved execution
|