@gajae-code/coding-agent 0.7.3 → 0.7.4
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 +48 -0
- package/bin/gjc.js +4 -0
- package/dist/types/cli/plugin-cli.d.ts +2 -0
- package/dist/types/commands/plugin.d.ts +6 -0
- package/dist/types/commands/session.d.ts +6 -0
- package/dist/types/config/model-profile-activation.d.ts +8 -1
- package/dist/types/extensibility/gjc-plugins/compiler.d.ts +19 -0
- package/dist/types/extensibility/gjc-plugins/constrained-hooks.d.ts +29 -0
- package/dist/types/extensibility/gjc-plugins/index.d.ts +9 -0
- package/dist/types/extensibility/gjc-plugins/injection.d.ts +9 -0
- package/dist/types/extensibility/gjc-plugins/installer.d.ts +13 -0
- package/dist/types/extensibility/gjc-plugins/mcp-policy.d.ts +26 -0
- package/dist/types/extensibility/gjc-plugins/observability.d.ts +27 -0
- package/dist/types/extensibility/gjc-plugins/prompt-appendix.d.ts +16 -0
- package/dist/types/extensibility/gjc-plugins/registry.d.ts +32 -0
- package/dist/types/extensibility/gjc-plugins/runtime-adapters.d.ts +64 -0
- package/dist/types/extensibility/gjc-plugins/session-validation.d.ts +42 -0
- package/dist/types/extensibility/gjc-plugins/types.d.ts +158 -2
- package/dist/types/extensibility/gjc-plugins/validation.d.ts +8 -1
- package/dist/types/gjc-runtime/launch-tmux.d.ts +1 -0
- package/dist/types/gjc-runtime/psmux-detect.d.ts +78 -0
- package/dist/types/gjc-runtime/team-runtime.d.ts +2 -0
- package/dist/types/gjc-runtime/tmux-common.d.ts +20 -1
- package/dist/types/gjc-runtime/tmux-sessions.d.ts +18 -0
- package/dist/types/main.d.ts +2 -0
- package/dist/types/modes/components/model-selector.d.ts +6 -0
- package/dist/types/notifications/html-format.d.ts +11 -0
- package/dist/types/notifications/index.d.ts +149 -1
- package/dist/types/notifications/lifecycle-commands.d.ts +72 -0
- package/dist/types/notifications/lifecycle-control-runtime.d.ts +98 -0
- package/dist/types/notifications/lifecycle-orchestrator.d.ts +144 -0
- package/dist/types/notifications/rate-limit-pool.d.ts +2 -0
- package/dist/types/notifications/recent-activity.d.ts +35 -0
- package/dist/types/notifications/telegram-daemon.d.ts +60 -0
- package/dist/types/notifications/telegram-reference.d.ts +3 -1
- package/dist/types/notifications/topic-registry.d.ts +10 -9
- package/dist/types/runtime-mcp/types.d.ts +7 -0
- package/dist/types/sdk.d.ts +2 -0
- package/dist/types/session/agent-session.d.ts +14 -4
- package/dist/types/session/blob-store.d.ts +25 -0
- package/dist/types/session/session-manager.d.ts +57 -0
- package/dist/types/slash-commands/helpers/fast-status-report.d.ts +6 -0
- package/dist/types/system-prompt.d.ts +2 -0
- package/dist/types/task/executor.d.ts +9 -1
- package/dist/types/tools/index.d.ts +3 -1
- package/dist/types/utils/changelog.d.ts +1 -0
- package/package.json +11 -9
- package/scripts/g004-tmux-smoke.ts +100 -0
- package/scripts/g005-daemon-smoke.ts +181 -0
- package/scripts/g011-daemon-path-smoke.ts +153 -0
- package/src/cli/plugin-cli.ts +66 -3
- package/src/cli.ts +21 -4
- package/src/commands/plugin.ts +4 -0
- package/src/commands/session.ts +18 -0
- package/src/config/model-profile-activation.ts +55 -7
- package/src/defaults/gjc/extensions/grok-cli-vendor/biome.json +1 -1
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +3 -3
- package/src/defaults/gjc/skills/team/SKILL.md +5 -4
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +41 -13
- package/src/export/html/index.ts +2 -2
- package/src/extensibility/gjc-plugins/compiler.ts +351 -0
- package/src/extensibility/gjc-plugins/constrained-hooks.ts +170 -0
- package/src/extensibility/gjc-plugins/index.ts +9 -0
- package/src/extensibility/gjc-plugins/injection.ts +109 -0
- package/src/extensibility/gjc-plugins/installer.ts +434 -0
- package/src/extensibility/gjc-plugins/loader.ts +3 -1
- package/src/extensibility/gjc-plugins/mcp-policy.ts +239 -0
- package/src/extensibility/gjc-plugins/observability.ts +84 -0
- package/src/extensibility/gjc-plugins/paths.ts +1 -1
- package/src/extensibility/gjc-plugins/prompt-appendix.ts +109 -0
- package/src/extensibility/gjc-plugins/registry.ts +180 -0
- package/src/extensibility/gjc-plugins/runtime-adapters.ts +234 -0
- package/src/extensibility/gjc-plugins/schema.ts +250 -20
- package/src/extensibility/gjc-plugins/session-validation.ts +147 -0
- package/src/extensibility/gjc-plugins/types.ts +199 -3
- package/src/extensibility/gjc-plugins/validation.ts +80 -0
- package/src/extensibility/skills.ts +15 -0
- package/src/gjc-runtime/launch-tmux.ts +61 -7
- package/src/gjc-runtime/psmux-detect.ts +239 -0
- package/src/gjc-runtime/team-runtime.ts +56 -23
- package/src/gjc-runtime/tmux-common.ts +27 -2
- package/src/gjc-runtime/tmux-sessions.ts +51 -1
- package/src/gjc-runtime/ultragoal-runtime.ts +75 -15
- package/src/internal-urls/docs-index.generated.ts +5 -4
- package/src/main.ts +14 -3
- package/src/modes/components/hook-editor.ts +1 -1
- package/src/modes/components/hook-selector.ts +67 -43
- package/src/modes/components/model-selector.ts +44 -11
- package/src/modes/controllers/extension-ui-controller.ts +0 -27
- package/src/modes/controllers/selector-controller.ts +50 -11
- package/src/modes/interactive-mode.ts +2 -0
- package/src/modes/utils/hotkeys-markdown.ts +1 -1
- package/src/notifications/html-format.ts +38 -0
- package/src/notifications/index.ts +242 -12
- package/src/notifications/lifecycle-commands.ts +228 -0
- package/src/notifications/lifecycle-control-runtime.ts +400 -0
- package/src/notifications/lifecycle-orchestrator.ts +358 -0
- package/src/notifications/rate-limit-pool.ts +19 -0
- package/src/notifications/recent-activity.ts +132 -0
- package/src/notifications/telegram-daemon.ts +433 -8
- package/src/notifications/telegram-reference.ts +25 -7
- package/src/notifications/topic-registry.ts +18 -9
- package/src/prompts/agents/executor.md +2 -2
- package/src/runtime-mcp/transports/stdio.ts +38 -4
- package/src/runtime-mcp/types.ts +7 -0
- package/src/sdk.ts +157 -10
- package/src/session/agent-session.ts +166 -74
- package/src/session/blob-store.ts +196 -8
- package/src/session/session-manager.ts +678 -7
- package/src/slash-commands/builtin-registry.ts +23 -3
- package/src/slash-commands/helpers/fast-status-report.ts +13 -3
- package/src/system-prompt.ts +9 -0
- package/src/task/executor.ts +31 -7
- package/src/task/index.ts +2 -0
- package/src/tools/ask.ts +5 -1
- package/src/tools/index.ts +3 -1
- package/src/utils/changelog.ts +8 -0
|
@@ -7,8 +7,13 @@ import {
|
|
|
7
7
|
formatAvailableProfileNames,
|
|
8
8
|
resolveProfileBindings,
|
|
9
9
|
} from "./model-profiles";
|
|
10
|
-
import {
|
|
11
|
-
|
|
10
|
+
import {
|
|
11
|
+
GJC_MODEL_ASSIGNMENT_TARGETS,
|
|
12
|
+
type GjcModelAssignmentTargetId,
|
|
13
|
+
isAuthenticated,
|
|
14
|
+
type ModelRegistry,
|
|
15
|
+
} from "./model-registry";
|
|
16
|
+
import { formatModelSelectorValue, resolveModelRoleValue } from "./model-resolver";
|
|
12
17
|
import type { Settings } from "./settings";
|
|
13
18
|
|
|
14
19
|
const LEGACY_MODEL_PROFILE_ALIASES: ReadonlyMap<string, string> = new Map([["codex-standard", "codex-medium"]]);
|
|
@@ -60,6 +65,48 @@ export interface PreparedModelProfileActivation {
|
|
|
60
65
|
*/
|
|
61
66
|
previousSessionDefaultModel: string | undefined;
|
|
62
67
|
}
|
|
68
|
+
export interface MaterializeModelProfileAssignmentOptions {
|
|
69
|
+
session: Pick<
|
|
70
|
+
ModelProfileActivationSession,
|
|
71
|
+
"model" | "thinkingLevel" | "setActiveModelProfile" | "getActiveModelProfile"
|
|
72
|
+
>;
|
|
73
|
+
settings: Pick<Settings, "clearOverride" | "get" | "override" | "set">;
|
|
74
|
+
role: GjcModelAssignmentTargetId;
|
|
75
|
+
selector: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function materializeActiveModelProfileAssignment(options: MaterializeModelProfileAssignmentOptions): boolean {
|
|
79
|
+
const activeProfile = options.session.getActiveModelProfile?.() ?? options.settings.get("modelProfile.default");
|
|
80
|
+
if (!activeProfile) return false;
|
|
81
|
+
|
|
82
|
+
const nextModelRoles = { ...options.settings.get("modelRoles") };
|
|
83
|
+
const nextAgentModelOverrides = { ...options.settings.get("task.agentModelOverrides") };
|
|
84
|
+
const target = GJC_MODEL_ASSIGNMENT_TARGETS[options.role];
|
|
85
|
+
|
|
86
|
+
if (options.role === "default") {
|
|
87
|
+
nextModelRoles.default = options.selector;
|
|
88
|
+
} else if (!nextModelRoles.default && options.session.model) {
|
|
89
|
+
nextModelRoles.default = formatModelSelectorValue(
|
|
90
|
+
`${options.session.model.provider}/${options.session.model.id}`,
|
|
91
|
+
options.session.thinkingLevel,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (target.settingsPath === "modelRoles") {
|
|
96
|
+
nextModelRoles[options.role] = options.selector;
|
|
97
|
+
} else {
|
|
98
|
+
nextAgentModelOverrides[options.role] = options.selector;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
options.settings.set("modelRoles", nextModelRoles);
|
|
102
|
+
options.settings.set("task.agentModelOverrides", nextAgentModelOverrides);
|
|
103
|
+
options.settings.set("modelProfile.default", undefined);
|
|
104
|
+
options.settings.clearOverride("modelProfile.default");
|
|
105
|
+
options.settings.override("modelRoles", nextModelRoles);
|
|
106
|
+
options.settings.override("task.agentModelOverrides", nextAgentModelOverrides);
|
|
107
|
+
options.session.setActiveModelProfile?.(undefined);
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
63
110
|
|
|
64
111
|
export function formatModelProfileCredentialError(profileName: string, providers: readonly string[]): string {
|
|
65
112
|
return `Model profile "${profileName}" requires credentials for: ${providers.join(", ")}. Run /login and configure the missing provider(s), then retry.`;
|
|
@@ -255,20 +302,19 @@ export async function applyPreparedModelProfileActivation(
|
|
|
255
302
|
modelChanged = true;
|
|
256
303
|
}
|
|
257
304
|
if (Object.keys(prepared.modelRoles).length > 0) {
|
|
258
|
-
prepared.settings.override("modelRoles", {
|
|
259
|
-
...prepared.settings.get("modelRoles"),
|
|
260
|
-
...prepared.modelRoles,
|
|
261
|
-
});
|
|
305
|
+
prepared.settings.override("modelRoles", { ...previousModelRoles, ...prepared.modelRoles });
|
|
262
306
|
modelRolesChanged = true;
|
|
263
307
|
}
|
|
264
308
|
if (Object.keys(prepared.agentModelOverrides).length > 0) {
|
|
265
309
|
prepared.settings.override("task.agentModelOverrides", {
|
|
266
|
-
...
|
|
310
|
+
...previousAgentModelOverrides,
|
|
267
311
|
...prepared.agentModelOverrides,
|
|
268
312
|
});
|
|
269
313
|
overridesChanged = true;
|
|
270
314
|
}
|
|
271
315
|
if (options.persistDefault) {
|
|
316
|
+
prepared.settings.set("modelRoles", {});
|
|
317
|
+
prepared.settings.set("task.agentModelOverrides", {});
|
|
272
318
|
prepared.settings.set("modelProfile.default", prepared.profileName);
|
|
273
319
|
defaultChanged = true;
|
|
274
320
|
await prepared.settings.flush();
|
|
@@ -277,6 +323,8 @@ export async function applyPreparedModelProfileActivation(
|
|
|
277
323
|
} catch (error) {
|
|
278
324
|
if (defaultChanged) {
|
|
279
325
|
prepared.settings.set("modelProfile.default", previousPersistedDefault);
|
|
326
|
+
prepared.settings.set("modelRoles", previousModelRoles);
|
|
327
|
+
prepared.settings.set("task.agentModelOverrides", previousAgentModelOverrides);
|
|
280
328
|
}
|
|
281
329
|
if (modelRolesChanged) {
|
|
282
330
|
prepared.settings.override("modelRoles", previousModelRoles);
|
|
@@ -458,7 +458,7 @@ Also recompute and persist `ambiguity_milestone` each round (detect band transit
|
|
|
458
458
|
|
|
459
459
|
- **Round 3+**: Allow early exit if user says "enough", "let's go", "build it"
|
|
460
460
|
- **Round 10**: Show soft warning: "We're at 10 rounds. Current ambiguity: {score}%. Continue or proceed with current clarity?"
|
|
461
|
-
- **Round
|
|
461
|
+
- **Round 100**: Hard cap: "Maximum interview rounds reached. Proceeding with current clarity level ({score}%)."
|
|
462
462
|
|
|
463
463
|
## Phase 3: Lateral Review Panel (milestone-triggered)
|
|
464
464
|
|
|
@@ -788,7 +788,7 @@ Why bad: 45% ambiguity means nearly half the requirements are unclear. The mathe
|
|
|
788
788
|
</Examples>
|
|
789
789
|
|
|
790
790
|
<Escalation_And_Stop_Conditions>
|
|
791
|
-
- **Hard cap at
|
|
791
|
+
- **Hard cap at 100 rounds**: Proceed with whatever clarity exists, noting the risk
|
|
792
792
|
- **Soft warning at 10 rounds**: Offer to continue or proceed
|
|
793
793
|
- **Early exit (round 3+)**: Allow with warning if ambiguity > threshold
|
|
794
794
|
- **User says "stop", "cancel", "abort"**: Stop immediately, save state for resume
|
|
@@ -823,7 +823,7 @@ Optional settings in `.gjc/settings.json`:
|
|
|
823
823
|
"gjc": {
|
|
824
824
|
"deepInterview": {
|
|
825
825
|
"ambiguityThreshold": <resolvedThreshold>,
|
|
826
|
-
"maxRounds":
|
|
826
|
+
"maxRounds": 100,
|
|
827
827
|
"softWarningRounds": 10,
|
|
828
828
|
"minRoundsBeforeExit": 3,
|
|
829
829
|
"enableChallengeAgents": true,
|
|
@@ -68,7 +68,7 @@ requiring a separate linked execution loop up front. GJC team supports current-w
|
|
|
68
68
|
|
|
69
69
|
Use `$ultragoal` for durable leader-owned goal/ledger tracking and `$team` for parallel visible tmux execution lanes. When Team is launched with an active `.gjc/_session-{sessionid}/ultragoal/goals.json`, worker task/status context may include leader-owned Ultragoal context: `.gjc/_session-{sessionid}/ultragoal/goals.json`, `.gjc/_session-{sessionid}/ultragoal/ledger.jsonl`, the active goal id, GJC goal mode, and the `fresh_leader_goal_get_required` checkpoint policy.
|
|
70
70
|
|
|
71
|
-
Workers provide task status and verification evidence only. They do not own Ultragoal goal state, create worker ledgers, mutate `.gjc/_session-{sessionid}/ultragoal`, auto-launch Team from Ultragoal, or perform hidden GJC goal mutation. Workers must not run `gjc ultragoal checkpoint`; checkpoint authority stays with the leader after worker tasks are terminal. Ultragoal does not auto-launch Team and performs no hidden goal mutation. The leader uses terminal Team evidence plus
|
|
71
|
+
Workers provide task status and verification evidence only. They do not own Ultragoal goal state, create worker ledgers, mutate `.gjc/_session-{sessionid}/ultragoal`, auto-launch Team from Ultragoal, or perform hidden GJC goal mutation. Workers must not run `gjc ultragoal checkpoint`; checkpoint authority stays with the leader after worker tasks are terminal. Ultragoal does not auto-launch Team and performs no hidden goal mutation. The leader uses terminal Team evidence plus the current-session active GJC goal snapshot and strict quality gate to run `gjc ultragoal checkpoint --goal-id <id> --status complete --evidence "<team evidence mentioning .gjc/_session-{sessionid}/ultragoal and <id>>" --quality-gate-json <quality-gate-json-or-path>`.
|
|
72
72
|
|
|
73
73
|
### Worker command override
|
|
74
74
|
|
|
@@ -311,9 +311,10 @@ Worker protocol:
|
|
|
311
311
|
Useful runtime env vars:
|
|
312
312
|
|
|
313
313
|
- `GJC_TMUX_COMMAND` / `GJC_TEAM_TMUX_COMMAND`
|
|
314
|
-
- tmux binary/name override (default `tmux`). `GJC_TMUX_COMMAND` applies to every GJC tmux flow; `GJC_TEAM_TMUX_COMMAND` is honored as an alias by the team path. Both resolve through the same resolver, so the team leader and `gjc session ...` always target the same multiplexer. These values are executable path/name overrides, not shell command lines; do not include flags such as `psmux -L <namespace>` in the env var.
|
|
315
|
-
- Windows psmux
|
|
316
|
-
- Multiplexer
|
|
314
|
+
- tmux binary/name override (default `tmux` on POSIX, `psmux` / `pmux` / `tmux` on native Windows when one of those resolves on PATH). `GJC_TMUX_COMMAND` applies to every GJC tmux flow; `GJC_TEAM_TMUX_COMMAND` is honored as an alias by the team path. Both resolve through the same resolver, so the team leader and `gjc session ...` always target the same multiplexer. These values are executable path/name overrides, not shell command lines; do not include flags such as `psmux -L <namespace>` in the env var.
|
|
315
|
+
- Native Windows psmux support: psmux is the supported tmux-compatible multiplexer for native Windows `gjc --tmux`, `gjc session`, and `gjc team`. Psmux can be exposed as `psmux.exe` or as its `tmux.exe`/`pmux.exe` aliases. GJC probes `psmux` / `pmux` / `tmux` on Windows PATH, picks the first that resolves, and treats that binary as the multiplexer. Worker commands on Windows are emitted with PowerShell-safe `$env:VAR = 'value';` assignments so psmux's ConPTY panes inherit `GJC_TEAM_*` correctly.
|
|
316
|
+
- Multiplexer detection knobs (Windows): `GJC_PSMUX_COMMAND` forces a wrapper to be treated as psmux, `GJC_PSMUX_DETECTION=off` skips detection, `GJC_PSMUX_FORCE_DETECT=1` re-probes every call. The mouse / set-clipboard / mode-style UX profile is filtered out for psmux; the `@gjc-profile` ownership tag and branch / project / session identity markers still round-trip and are required for `gjc session` and `gjc team`.
|
|
317
|
+
- Windows psmux namespace boundary: psmux `-c <path>` cwd/start-directory flags do not isolate the server namespace; psmux uses the tmux-compatible global `-L <namespace>` flag for isolated server instances. GJC does not currently expose structured runtime `-L` support, because launch, `gjc session`, and `gjc team` must all carry the same namespace prefix together. If you need isolated psmux servers, start `psmux -L <namespace>` yourself before `gjc --tmux` and let GJC attach to it; do not pass `-L` through `GJC_TMUX_COMMAND`.
|
|
317
318
|
- `GJC_TEAM_WORKER_COMMAND`
|
|
318
319
|
- worker command override (default resolves to active GJC entrypoint or `gjc`)
|
|
319
320
|
- `GJC_TEAM_STATE_ROOT`
|
|
@@ -34,7 +34,7 @@ gjc ultragoal create-goals --brief "<brief>"
|
|
|
34
34
|
gjc ultragoal create-goals --brief-file <path>
|
|
35
35
|
gjc ultragoal complete-goals
|
|
36
36
|
gjc ultragoal complete-goals --retry-failed
|
|
37
|
-
gjc ultragoal checkpoint --goal-id <id> --status complete --evidence "<evidence>" --
|
|
37
|
+
gjc ultragoal checkpoint --goal-id <id> --status complete --evidence "<evidence>" --quality-gate-json <quality-gate-json-or-path>
|
|
38
38
|
gjc ultragoal checkpoint --goal-id <id> --status failed --evidence "<blocker/evidence>"
|
|
39
39
|
gjc ultragoal record-review-blockers --goal-id <id> --title "Resolve final review blockers" --objective "<blocker-resolution objective>" --evidence "<review findings>" --gjc-goal-json <active-goal-get-json-or-path>
|
|
40
40
|
```
|
|
@@ -50,7 +50,7 @@ goal({"op":"resume"})
|
|
|
50
50
|
```
|
|
51
51
|
`drop` clears the active goal without exiting goal mode; `resume` reactivates a paused goal.
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
Complete checkpoints source the active GJC goal snapshot from the current session when `--gjc-goal-json` is omitted. Use an explicit `--gjc-goal-json` only as an override; supplied values are still strictly validated and must be active goal-mode snapshots, not `.gjc/ultragoal/goals.json` records.
|
|
54
54
|
|
|
55
55
|
## Create goals
|
|
56
56
|
|
|
@@ -97,9 +97,9 @@ Loop until `gjc ultragoal status` reports all goals complete:
|
|
|
97
97
|
4. If no active GJC goal exists, call `goal({"op":"create","objective":"<printed payload objective>"})` with the printed payload. In aggregate mode, if the same aggregate objective is already active, continue the current GJC story without creating a new GJC goal. If `goal({"op":"get"})` shows a stale dropped goal (status `"dropped"`) and a new aggregate must start, no extra cleanup is needed — `goal({"op":"create"})` succeeds directly. If a previous aggregate is still active and you genuinely need a fresh start in the same session, call `goal({"op":"drop"})` first, then `goal({"op":"create"})`.
|
|
98
98
|
5. Complete the current GJC story only.
|
|
99
99
|
6. Run a completion audit against the story objective and real artifacts/tests.
|
|
100
|
-
7. Before any `--status complete` checkpoint, run the mandatory final cleanup/review gate below. In aggregate mode, do **not** call `goal({"op":"complete"})` for intermediate stories; checkpoint each story
|
|
101
|
-
8. Checkpoint the durable ledger
|
|
102
|
-
`gjc ultragoal checkpoint --goal-id <id> --status complete --evidence "<evidence>" --
|
|
100
|
+
7. Before any `--status complete` checkpoint, run the mandatory final cleanup/review gate below. In aggregate mode, do **not** call `goal({"op":"complete"})` for intermediate stories; checkpoint each story while the aggregate objective is still `active`. On the final story, create the final aggregate receipt first; only after that receipt exists may `goal({"op":"complete"})` run.
|
|
101
|
+
8. Checkpoint the durable ledger. Complete checkpoints require `--quality-gate-json`; the runtime sources the active GJC goal snapshot from current session state when `--gjc-goal-json` is omitted, and rejects any explicitly supplied bad snapshot:
|
|
102
|
+
`gjc ultragoal checkpoint --goal-id <id> --status complete --evidence "<evidence>" --quality-gate-json <quality-gate-json-or-path>`
|
|
103
103
|
A successful complete checkpoint is story completion, not automatic run completion. Read the checkpoint output: when it prints `Next ultragoal goal: <id>`, continue that active story under the same aggregate GJC goal; when it prints `All ultragoal goals are complete`, the durable run is terminal. `gjc ultragoal complete-goals` remains the supported manual next-story command if continuation output was missed.
|
|
104
104
|
9. If blocked or failed, checkpoint failure:
|
|
105
105
|
`gjc ultragoal checkpoint --goal-id <id> --status failed --evidence "<blocker/evidence>"`
|
|
@@ -179,10 +179,10 @@ For large subgoals with independent slices, the Ultragoal leader must spawn para
|
|
|
179
179
|
|
|
180
180
|
Use ultragoal and team together for a durable Ultragoal story that benefits from one visible tmux worker session. Ultragoal remains leader-owned: `.gjc/_session-{sessionid}/ultragoal/goals.json` stores the story plan and `.gjc/_session-{sessionid}/ultragoal/ledger.jsonl` stores checkpoints. Team is the single-worker tmux execution engine and returns task/evidence status to the leader.
|
|
181
181
|
|
|
182
|
-
The leader checkpoints Ultragoal from Team evidence
|
|
182
|
+
The leader checkpoints Ultragoal from Team evidence; the runtime uses the active current-session GJC goal snapshot unless an explicit `--gjc-goal-json` override is supplied:
|
|
183
183
|
|
|
184
184
|
```sh
|
|
185
|
-
gjc ultragoal checkpoint --goal-id <id> --status complete --evidence "<team evidence mentioning .gjc/_session-{sessionid}/ultragoal and <id>>" --
|
|
185
|
+
gjc ultragoal checkpoint --goal-id <id> --status complete --evidence "<team evidence mentioning .gjc/_session-{sessionid}/ultragoal and <id>>" --quality-gate-json <quality-gate-json-or-path>
|
|
186
186
|
```
|
|
187
187
|
|
|
188
188
|
Workers do not own ultragoal goal state, do not create worker ultragoal ledgers, and do not checkpoint Ultragoal. Workers must not run `gjc ultragoal checkpoint`; checkpoint authority stays with the leader after worker tasks are terminal. Team launch remains explicit; Ultragoal does not auto-launch Team and performs no hidden goal mutation.
|
|
@@ -211,9 +211,9 @@ An ultragoal story cannot be checkpointed `complete` until the active agent has
|
|
|
211
211
|
5. Delegate an `executor` QA/red-team lane to build and run the e2e/read-teaming QA suite appropriate for the story. This lane must try to break the change, not just confirm the happy path. It must start from the approved plan/spec/acceptance criteria, then user-facing contracts, and only then implementation code as supporting evidence. Plan/code mismatches are blockers, not items to paper over with implementation intent.
|
|
212
212
|
6. The executor QA/red-team lane must prove evidence by the real surface under test:
|
|
213
213
|
- GUI/web surfaces require a valid automation transcript plus a non-uniform screenshot. Bare `inlineEvidence` text or typed receipts never prove live GUI/web execution.
|
|
214
|
-
- CLI surfaces require runtime argv replay: `replaySafe: true`, an allowlisted argv `command`, and replayed normalized stdout matching `recordedStdout
|
|
214
|
+
- CLI surfaces require runtime argv replay: `replaySafe: true`, an allowlisted argv `command`, and replayed normalized stdout matching `recordedStdout`. The conservative allowlist is intentionally small: `bun --version`, `node --version`, deterministic `bun/node -e "console.log(...)"`, `npm|pnpm|yarn --version`, `npm|pnpm|yarn list`, read-only `git status|rev-parse|merge-base|diff|show|log` with safe args, and `gjc read|status`. Unsafe, non-deterministic, credentialed, interactive, or otherwise unallowlisted commands require audited `replayExempt` metadata with exact fields `reasonCode`, `reason`, `approvedBy`, and `fallbackArtifactRefs` plus a structurally valid fallback artifact. Allowed `reasonCode` values are exactly `unsafe_side_effect`, `requires_credentials`, `requires_network`, `non_deterministic_external`, `destructive`, `interactive_only`, and `platform_unavailable`.
|
|
215
215
|
- Native/desktop/tui surfaces require a structurally valid screenshot, PTY capture with terminal control codes, or app-automation transcript.
|
|
216
|
-
- API/package/
|
|
216
|
+
- API/package surfaces require a real artifact file or typed receipt whose artifact `kind` contains one of `api`, `package`, `consumer`, `black-box`, or `test-report`; examples: `api-package-test-report`, `package-consumer-report`, `black-box-api-receipt`. Algorithm/math surfaces require a real artifact file or typed receipt whose artifact `kind` contains one of `property`, `boundary`, `edge`, `adversarial`, `failure`, `math`, `algorithm`, or `test-report`; examples: `property-test-report`, `algorithm-boundary-report`. Bare `inlineEvidence` text alone is not sufficient for any surface.
|
|
217
217
|
- The mandatory **computer-use** red-team suite (`kill-switch-bypass`, `suspended-enforcement`, `permission-revoked`, …) is conditional, not universal: require it only when computer/desktop control is genuinely part of the product surface being dogfooded. For every other product type, prove the change through the matching live surface instead — browser-use automation for web/GUI, bash/CLI live invocation or argv replay for CLI, and real artifacts or typed receipts for API/package/algorithm/math. Editing docs, prompts, or skills that merely mention computer-use does not by itself make the computer-use suite applicable; pick the red-team surface that matches what the change actually ships.
|
|
218
218
|
7. The executor QA/red-team lane must report a matrix using `executorQa.contractCoverage`, `executorQa.surfaceEvidence`, `executorQa.adversarialCases`, and `executorQa.artifactRefs`. Not-applicable rows are allowed only in `contractCoverage` and `surfaceEvidence`; each `status: "not_applicable"` row requires `contractRef` plus `reason`. `adversarialCases` rows cannot be not-applicable.
|
|
219
219
|
8. Run a final code review pass and fold it into the strict quality gate. Clean means `architectReview.architectureStatus`, `architectReview.productStatus`, and `architectReview.codeStatus` are all `"CLEAR"`, `architectReview.recommendation` is `"APPROVE"`, executor QA statuses are `"passed"`, iteration is `"passed"` with `fullRerun: true`, every evidence field is non-empty, every required matrix row is present, and every blockers array is empty. `COMMENT`, `WATCH`, `REQUEST CHANGES`, `BLOCK`, missing evidence, missing or shallow matrix rows, plan/code mismatches, or non-empty blockers are non-clean.
|
|
@@ -222,7 +222,7 @@ An ultragoal story cannot be checkpointed `complete` until the active agent has
|
|
|
222
222
|
gjc ultragoal record-review-blockers --goal-id <id> --title "Resolve verification blockers" --objective "<blocker-resolution objective>" --evidence "<architect/executor findings>" --gjc-goal-json <active-goal-get-json-or-path>
|
|
223
223
|
```
|
|
224
224
|
10. Complete or steer through the blocker story, then rerun the full blocking verification loop. Repeat until all verifier lanes are clean.
|
|
225
|
-
11. Only after the loop is clean, checkpoint the story as complete with a structured quality gate and
|
|
225
|
+
11. Only after the loop is clean, checkpoint the story as complete with a structured quality gate and current-session active goal snapshot. The checkpoint creates a receipt; `goals.json.status` alone is not proof. In aggregate mode, the final aggregate receipt must exist before `goal({"op":"complete"})` is allowed.
|
|
226
226
|
|
|
227
227
|
While an Ultragoal run is active, the `ask` tool is blocked for all agents. Record unresolved review decisions as durable blockers with `gjc ultragoal record-review-blockers` instead of prompting interactively.
|
|
228
228
|
|
|
@@ -263,13 +263,25 @@ The native `checkpoint --status complete` command rejects missing or shallow gat
|
|
|
263
263
|
"id": "cli-replay",
|
|
264
264
|
"kind": "command-replay",
|
|
265
265
|
"path": "artifacts/cli-replay.json",
|
|
266
|
-
"description": "artifact file containing argv-only CLI replay JSON: schemaVersion 1, kind cli-replay, replaySafe true, allowlisted command, recordedStdout"
|
|
266
|
+
"description": "artifact file containing argv-only CLI replay JSON: schemaVersion 1, kind cli-replay, replaySafe true, allowlisted command such as bun/node --version or deterministic bun/node -e console.log(...), recordedStdout"
|
|
267
267
|
},
|
|
268
268
|
{
|
|
269
269
|
"id": "adversarial-report",
|
|
270
270
|
"kind": "failure-mode-test",
|
|
271
271
|
"path": "artifacts/adversarial-report.txt",
|
|
272
272
|
"description": "boundary, property, adversarial, or failure-mode result"
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"id": "api-package-report",
|
|
276
|
+
"kind": "api-package-test-report",
|
|
277
|
+
"path": "artifacts/api-package-report.txt",
|
|
278
|
+
"description": "API/package consumer or endpoint verification output"
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
"id": "algorithm-report",
|
|
282
|
+
"kind": "property-test-report",
|
|
283
|
+
"path": "artifacts/algorithm-report.txt",
|
|
284
|
+
"description": "Algorithm/math property, boundary, or invariant verification output"
|
|
273
285
|
}
|
|
274
286
|
],
|
|
275
287
|
"contractCoverage": [
|
|
@@ -306,6 +318,22 @@ The native `checkpoint --status complete` command rejects missing or shallow gat
|
|
|
306
318
|
"verdict": "passed",
|
|
307
319
|
"artifactRefs": ["cli-replay"]
|
|
308
320
|
},
|
|
321
|
+
{
|
|
322
|
+
"id": "surface-api",
|
|
323
|
+
"contractRef": "API/package public interface under test",
|
|
324
|
+
"surface": "api/package",
|
|
325
|
+
"invocation": "real endpoint call, package consumer call, or schema contract check",
|
|
326
|
+
"verdict": "passed",
|
|
327
|
+
"artifactRefs": ["api-package-report"]
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
"id": "surface-algorithm",
|
|
331
|
+
"contractRef": "algorithm/math invariant under test",
|
|
332
|
+
"surface": "algorithm/math",
|
|
333
|
+
"invocation": "property, boundary, or invariant test run",
|
|
334
|
+
"verdict": "passed",
|
|
335
|
+
"artifactRefs": ["algorithm-report"]
|
|
336
|
+
},
|
|
309
337
|
{
|
|
310
338
|
"id": "surface-out-of-scope",
|
|
311
339
|
"contractRef": "surface intentionally outside this story",
|
|
@@ -364,6 +392,6 @@ The skill tool then dispatches `/skill:ralplan` or `/skill:deep-interview` same-
|
|
|
364
392
|
- For back-to-back ultragoal runs in the same session/thread, when `goal({"op":"get"})` still reports an active aggregate, call `goal({"op":"drop"})` before `goal({"op":"create"})`; when no active goal exists or the prior aggregate is already complete or dropped, call `goal({"op":"create"})` directly. The goal tool remains callable across drop; no slash-command cleanup exists or is required.
|
|
365
393
|
- Never call `goal({"op":"create"})` when `goal({"op":"get"})` reports a different active goal.
|
|
366
394
|
- Never call `goal({"op":"complete"})` unless the aggregate run or legacy per-story goal is actually complete.
|
|
367
|
-
- In aggregate mode, intermediate and final story checkpoints require a matching `active` GJC goal snapshot; the final story checkpoint creates the final aggregate receipt before `goal({"op":"complete"})` may reconcile the inline goal state.
|
|
368
|
-
- Completion checkpoints require read-only goal snapshot reconciliation:
|
|
395
|
+
- In aggregate mode, intermediate and final story checkpoints require a matching `active` GJC goal snapshot; omitted complete-checkpoint `--gjc-goal-json` reads that snapshot from current session state, and the final story checkpoint creates the final aggregate receipt before `goal({"op":"complete"})` may reconcile the inline goal state.
|
|
396
|
+
- Completion checkpoints require read-only goal snapshot reconciliation: omit `--gjc-goal-json` to use current session state, or pass an explicit JSON/path override that remains strictly validated; shell commands and hooks must not mutate goal state.
|
|
369
397
|
- Treat `ledger.jsonl` as the durable audit trail; checkpoint after every success or failure.
|
package/src/export/html/index.ts
CHANGED
|
@@ -125,7 +125,7 @@ export async function exportSessionToHtml(
|
|
|
125
125
|
|
|
126
126
|
const sessionData: SessionData = {
|
|
127
127
|
header: sm.getHeader(),
|
|
128
|
-
entries: sm.
|
|
128
|
+
entries: sm.getEntriesForExport(),
|
|
129
129
|
leafId: sm.getLeafId(),
|
|
130
130
|
systemPrompt: state?.systemPrompt.join("\n\n"),
|
|
131
131
|
tools: state?.tools?.map(t => ({ name: t.name, description: t.description })),
|
|
@@ -153,7 +153,7 @@ export async function exportFromFile(inputPath: string, options?: ExportOptions
|
|
|
153
153
|
try {
|
|
154
154
|
const sessionData: SessionData = {
|
|
155
155
|
header: sm.getHeader(),
|
|
156
|
-
entries: sm.
|
|
156
|
+
entries: sm.getEntriesForExport(),
|
|
157
157
|
leafId: sm.getLeafId(),
|
|
158
158
|
};
|
|
159
159
|
|