Skip to content

Commit 86dffab

Browse files
authored
Merge pull request #39 from devswha/codex/complete-followups
feat(gjc): complete managed workflows and session worktrees
2 parents f9561a9 + faff353 commit 86dffab

134 files changed

Lines changed: 9938 additions & 417 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/release.yml

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,9 @@ jobs:
144144
needs: release-policy
145145
timeout-minutes: 90
146146
runs-on: macos-14
147-
# The `release` environment holds the Developer ID certificate and the
148-
# notarization credentials. With them the job signs, notarizes and staples
149-
# the app and the image exactly as docs/DESKTOP-TAURI-VERIFICATION.md
150-
# § "Signed release procedure" does locally; without them it builds the
151-
# ad-hoc image it always has, so a fork or a checkout without the secrets
152-
# still produces a testable DMG.
147+
# Published desktop assets require Developer ID signing and notarization.
148+
# Local ad-hoc builds remain available through the packaging scripts.
149+
# See scripts/release/SIGNING-READINESS.md for read-only readiness checks.
153150
environment: release
154151
permissions:
155152
contents: read
@@ -195,6 +192,9 @@ jobs:
195192
echo "release_tag=v$RELEASE_VERSION"
196193
} >> "$GITHUB_OUTPUT"
197194
195+
- name: Require release signing credentials
196+
run: node scripts/release/check-signing-readiness.mjs --mode ci
197+
198198
- name: Set up Rust
199199
run: |
200200
set -euo pipefail
@@ -216,22 +216,13 @@ jobs:
216216
id: identity
217217
run: |
218218
set -euo pipefail
219-
if [ -z "${APPLE_CERTIFICATE_P12:-}" ]; then
220-
echo "No APPLE_CERTIFICATE_P12 in the release environment; building the ad-hoc image."
221-
echo "signed=false" >> "$GITHUB_OUTPUT"
222-
exit 0
223-
fi
224-
for name in APPLE_CERTIFICATE_PASSWORD APPLE_ID APPLE_TEAM_ID APPLE_APP_PASSWORD; do
225-
if [ -z "${!name:-}" ]; then
226-
echo "APPLE_CERTIFICATE_P12 is set but $name is not; refusing a half-configured signing lane." >&2
227-
exit 1
228-
fi
229-
done
230219
KEYCHAIN="$RUNNER_TEMP/gajae-signing.keychain-db"
231220
KEYCHAIN_PASSWORD="$(openssl rand -hex 24)"
232221
CERT="$RUNNER_TEMP/developer-id.p12"
233222
printf '%s' "$APPLE_CERTIFICATE_P12" | base64 --decode > "$CERT"
234223
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN"
224+
# Make cleanup run even if unlock/import/identity selection fails.
225+
echo "GAJAE_SIGNING_KEYCHAIN=$KEYCHAIN" >> "$GITHUB_ENV"
235226
security set-keychain-settings -lut 21600 "$KEYCHAIN"
236227
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN"
237228
security import "$CERT" -k "$KEYCHAIN" -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign -T /usr/bin/security
@@ -244,7 +235,6 @@ jobs:
244235
exit 1
245236
fi
246237
echo "APPLE_SIGNING_IDENTITY=$IDENTITY" >> "$GITHUB_ENV"
247-
echo "GAJAE_SIGNING_KEYCHAIN=$KEYCHAIN" >> "$GITHUB_ENV"
248238
echo "signed=true" >> "$GITHUB_OUTPUT"
249239
echo "Signing as: $IDENTITY"
250240
@@ -441,6 +431,16 @@ jobs:
441431
permissions:
442432
contents: write
443433
steps:
434+
- name: Require signed desktop before publication
435+
env:
436+
DESKTOP_SIGNED: ${{ needs.desktop-macos.outputs.signed }}
437+
run: |
438+
set -euo pipefail
439+
if [ "$DESKTOP_SIGNED" != "true" ]; then
440+
echo "Refusing to publish a desktop artifact without the signing and notarization lane." >&2
441+
exit 1
442+
fi
443+
444444
- name: Download canonical server release assets
445445
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
446446
with:

docs/GJC-DELEGATION-CONTRACT.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# App delegation and native workflows
2+
3+
`server/gjc-delegation-executor.ts` owns the app's `task` and `subagent`
4+
tools. The raw SDK task executor remains excluded: the offline regression in
5+
`server/gjc-sdk-contract.bun.test.ts` demonstrates its parent-permission bypass
6+
on SDK 0.16.4. Do not remove that regression or enable raw children to satisfy a
7+
workflow requirement.
8+
9+
Ordinary tasks use `executionMode: "default"`; omission and `null` also select
10+
ordinary execution. `"ultragoal-red-team"` requires the Executor role. Unused
11+
control fields and optional repository metadata accept `null` for strict
12+
provider schemas. Bindings are validated through the SDK's exported repository
13+
contract before approval and again at child startup/resume; they do not select
14+
a different child cwd. A different repository or escaping relative subdirectory
15+
is rejected.
16+
17+
Children retain the actual parent model, effort, credentials, permissions and
18+
tool allowlist. The direct owner's and root's native mutation/Ultragoal ask
19+
guards also apply to child tool calls. Each child has a distinct session ID and
20+
keeps GOAL disabled; the root adapter owns GOAL lifecycle and turn disposal.
21+
For AUTO credentials, the child pins the opaque stored row selected by the
22+
parent's authenticated request in its own credential scope. Resume reevaluates
23+
the current account and any new explicit pin; credential values never enter
24+
delegation receipts.
25+
26+
A rejected SDK abort is an unconfirmed cancellation. `cancel` and `dispose`
27+
return a sanitized failure and permit retry; disposal keeps new work fenced.
28+
Concurrent abort attempts share one pending SDK call. An owner remains open
29+
until its descendants actually stop, including after a descendant abort fails.
30+
31+
The `gajae-app.delegation.v1` transcript entries record child ownership and
32+
bounded result text. They are not native workflow completion receipts. Workflow
33+
assignments must carry their authoritative owner `session_id`, `run_id` and
34+
repository binding. Child prompts identify the app delegation ID, direct owner
35+
and root, and instruct writers to use the assignment's owner/run IDs explicitly.
36+
37+
The offline tests in `server/gjc-delegation-executor.bun.test.ts` exercise SDK
38+
0.16.4 public exports with real sessions, tools, transcripts and temporary Git
39+
repositories. A deterministic transport stands in for the model; it asserts
40+
`openai-codex/gpt-6-astra` with `xhigh` on every request and makes no network model
41+
calls. They establish these contracts:
42+
43+
- Ralplan: Planner artifacts and independent Architect/Critic reads flow through
44+
`gjc ralplan --write`; native receipts bind the actual child IDs and hashes.
45+
Resumed lanes retain their IDs. Native overwrite and user-approval/Stop guards
46+
remain effective after the review passes.
47+
- Ultragoal: independent lanes read a CLI fixture, execute it and provide real
48+
replay evidence. The owner joins their results and the Critic independently
49+
checks that join. Native validation rejects wrapper-only results, unjoined
50+
evidence and a false replay expectation. Only the native checkpoint writes
51+
the final aggregate completion receipt, verified by the durable-state guard.
52+
53+
These tests qualify the app-to-runtime contracts for the small fixtures; they
54+
do not establish live model orchestration, product QA quality, browser E2E,
55+
root GOAL lifecycle or packaged-app completion. Those require the parent
56+
integration's live runs and repository promotion gate.

docs/GJC-WORKER-PROTOCOL.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ scope is fixed by this specification, and a frame that gets it wrong is rejected
115115
| `turn.start` | scoped | Run a turn in an existing conversation. |
116116
| `turn.abort` | scoped | Stop the running turn. |
117117
| `turn.steer` | scoped | Inject input into the running turn without ending it. |
118+
| `goal.inspect` | scoped | Read the exact persisted provider session's goal for an authenticated owner and resolved project cwd; refuses an active run. |
119+
| `goal.control` | scoped | Read or control a goal on the exact worker `runId`; requires matching app session, owner, cwd, and expected goal ID. The trusted server may pass literal `stopAfterMutation: false` for pause/drop so the enclosing native worktree job owns cancellation. |
118120
| `ask.reply` | scoped | Answer a question the worker raised with `ask.presented`. |
119121

120122
### Events

docs/V2-SESSION-HANDOFF.md

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -478,10 +478,10 @@ after the reconcile fetch replaces realtime timestamps with disk ones.
478478
[`plans/adversarial-skills-e2e-2026-09-05.md`](plans/adversarial-skills-e2e-2026-09-05.md).
479479
DNS deployments now require explicit `ALLOWED_HOSTS`; see `SELF-HOST.md`.
480480
The app avoids the SDK workflow-ID defect by omitting the redundant explicit
481-
provider ID, and restores skill requests from transcript metadata. Delegation
482-
remains disabled because an offline real-SDK test proved that children bypass
483-
their parent's permission policy. Research/file artifacts do not mean that
484-
`ralplan`, `ultragoal` or the autoresearch goal lifecycle completed.
481+
provider ID, and restores skill requests from transcript metadata. The raw
482+
SDK delegation path remains unsafe. The follow-up implementation replaces
483+
it with app-owned children that inherit permissions, account, model/effort,
484+
workflow guards and cancellation; see `GJC-DELEGATION-CONTRACT.md`.
485485
- The parallel correctness pass is recorded in
486486
[`plans/code-review-2026-09-05.md`](plans/code-review-2026-09-05.md), including
487487
session/queue isolation, transcript turns and transport, scratch startup,
@@ -499,18 +499,29 @@ after the reconcile fetch replaces realtime timestamps with disk ones.
499499
response/abort smoke passed. The existing redundant-ID mitigation stays in
500500
place. The real-SDK child permission-bypass regression still reproduces on
501501
0.16.4; the identity fix does not qualify unrestricted delegation.
502-
- **Issue #3 now has a live matrix, with unresolved capability blockers.** The bundled `gjc`
503-
shim is already in the app; the issue's older "shim in progress" comment
504-
is no longer current. Nine skills were actually invoked, including user
505-
skills. The interview produced its pending-approval spec; mandatory
506-
delegation and goal-mode restrictions still prevent complete execution of
507-
the other bundled workflows. Keep #3 open for those recorded limitations.
502+
- **Issue #3 has a follow-up implementation and renewed live qualification.**
503+
Goal state now comes from the SDK transcript, with authenticated, scoped
504+
pause/resume/cancel controls and app-owned delegation. The initial 20-step
505+
lease stopped ordinary workflow preparation; the visible limit is now 200
506+
model steps or 120 minutes. Model-facing goal operations do not reset that lease. The interview
507+
and independently reviewed Ralplan plan reached their requested approval
508+
stopping points; autoresearch persisted its verdict, completed the goal and
509+
retired the mission. Ultragoal also passed native aggregate evidence and
510+
completed its real goal. Final acceptance is recorded in
511+
`plans/followup-acceptance.md`. #3 remains open for original Cursor/Anthropic
512+
live qualification and upstream workflow/CLI efficiency, outside the
513+
requested Astra-only test lane.
508514
- **CI signing awaits owner-provided credentials.** `gh secret list --env
509515
release` returned no environment secrets on September 5. The workflow
510516
and the five required names are documented in
511517
`DESKTOP-TAURI-VERIFICATION.md`; the first signed CI dispatch remains
512-
unverified. This is separate from the locally signed releases that shipped.
513-
- Session worktree selection still depends on the runtime's Slice 3.
518+
unverified. Local signing readiness and exact-draft asset verification are
519+
available in `scripts/release/SIGNING-READINESS.md` and
520+
`scripts/release/LOCAL-RELEASE.md`, without exporting signing credentials.
521+
- Managed session worktree selection is implemented on the existing native job
522+
runtime, including persisted project/cwd identity, per-run validation and
523+
cancellation. It does not await a future SDK Slice 3. See
524+
`plans/session-worktree-goal-acceptance.md`.
514525
Conversation forks and split-pane workspaces remain deferred product
515526
decisions, not missing implementations from the completed plans.
516527

docs/plans/followup-acceptance.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Remaining-work integration and acceptance
2+
3+
This follows PRs #30, #35 and #38, all merged after their required checks.
4+
All implementation/review agents and actual model requests used Astra with
5+
xhigh reasoning. Offline tests use controlled transports rather than another
6+
model. Final promotion checks are recorded below; live tests distinguish
7+
workflow completion from a turn merely ending.
8+
9+
## Changes and reproduced defects
10+
11+
| Area | Result |
12+
| --- | --- |
13+
| SDK identity | Pin 0.16.4, preserve the original regression input, update both native platform closures and generated command/notices data. Issue #18 closed through #30. |
14+
| Provider variants | Keep provider-qualified choices and test canonical collapse, account routing, cache migration and restart. #35 merged. |
15+
| Linux | #38 adds native deb/AppImage builds, Ubuntu 22.04/24.04 package/GUI/install checks, terminal ownership and AppImage environment fixes. Review additionally fixed stale socket reclamation and symlinked packaging entrypoints. |
16+
| Delegation | Replace unsafe SDK task/subagent executors with app-owned sessions; preserve actual AUTO account selection, model/effort, permissions, tools, native workflow guards, owned resume and retryable cancellation. Raw SDK bypass coverage remains. |
17+
| Goals | Project persisted SDK goal state; enforce owner/run/goal identity; show status, objective, usage and controls. Disk failures fence continuation. Stop remains retryable. Worktree controls use worker IDs while native job tickets own cancellation. |
18+
| Worktrees | Create an owned native job for a new isolated session; preserve parent project permissions/grouping and actual cwd through later turns, restart, files, skills, exports and Git views. Reject changed/foreign worktrees and conflicting transcript identities. |
19+
| Search | Search decoded GJC transcripts with bounded lines, identity/root checks and project filtering before result limits. Search concise skill requests, not expanded prompts. |
20+
| Replay | Scope cursors to run generations; reject obsolete/repeated frames; preserve navigation-time deltas; reconcile persisted answers/thinking even when reasoning separates them or the user anchor is outside the window. |
21+
| Cleanup | A branded unconfirmed cleanup fault quarantines the shared GJC worker. Node waits for verified whole-worker reaping before terminal settlement; failed reaping retains uncertainty and blocks new dispatch. Provider text cannot spoof the fault. |
22+
| UI | Stabilized picker remains from #37. Goal controls survive view/StrictMode lifecycle changes. Settings uses the owned dialog with named dismissal, focus restoration and Escape ownership. Live message counts do not claim stale totals. |
23+
| Release | Check signing prerequisites before publication, verify exact local draft assets and signatures, and retain mount directories if detachment cannot be confirmed. No signing private key is exported. |
24+
25+
Root goals have a cumulative **200 model-step / 120-minute** run lease.
26+
Tool-calling SDK turns count as steps. Explicit user resume starts a new run;
27+
model pause/resume does not reset that run's lease. Delegation retains four
28+
active children, depth two, 32 launches per run and a five-minute child limit.
29+
Observed Ralplan children completed within that child limit; the restrictive
30+
root 20-step limit, rather than a child timeout, interrupted the initial goal
31+
drills. Limits do not waive permissions or native completion evidence.
32+
33+
## Live skill outcomes
34+
35+
Tests use disposable Git projects, an isolated app database and session roots.
36+
The ordinary catalog consists of four bundled skills and five user skills.
37+
The QA OAuth connection was renewed through the existing browser sign-in flow.
38+
Sign-in values stayed outside application conversation transcripts and model
39+
prompts; credentials were not copied back into the normal app store.
40+
41+
| Skill | Evidence and disposition |
42+
| --- | --- |
43+
| deep-interview | Structured questions and approval UI worked; a short specification was saved pending approval with 1.6% final ambiguity. No implementation/handoff. `--quick` still yields the native pre-resolved 5% threshold. |
44+
| ralplan | Actual Planner, resumed Planner, independent Architect and Critic produced native validated artifacts. The operator selected Stop at the requested approval boundary. Source remained unchanged. |
45+
| autoresearch | Existing benchmark yielded baseline 11.5, candidate 8.5 and 26.09% reduction. Native verdict, matching goal completion and mission cleanup were observed. Small-sample limitations were retained. Initial unsupported CLI flags were corrected during the run. |
46+
| ultragoal | The exact 18-byte output and unchanged acceptance files were independently checked. Existing tests passed. Actual independent implementation/review/QA and terminal Critic evidence passed native validation; the durable aggregate receipt and real goal completion were observed. Earlier leases paused the workflow; explicit resume retained its identity and completed it. |
47+
| no-english (user) | Korean rewriting preserved paths, identifiers and executable commands. Passed. |
48+
| insane-search (user) | Public Example Domain read succeeded through the normal reader; no fallback engine was needed. Earlier private-target refusal was a separate negative test. |
49+
| gpt-image (user) | Image-generation lane cannot establish Astra-only generation. Initial isolated binding absence and a corrected-binding retry are recorded; no image success is claimed. |
50+
| insane-review (user) | Required Sol Pro lane conflicts with Astra-only execution. Refusal was verified; local checks are not an external review result. |
51+
| extragoal (user) | Correctly refused missing feature-branch/diff evidence and the unavailable cross-family reviewer. No fabricated approval or remote publication. |
52+
53+
Actual parent/child assistant records inspected so far contain only
54+
`openai-codex/gpt-6-astra` and `xhigh` thinking changes. Generic live Planner
55+
delegation returned the fixture heading through task/subagent.
56+
57+
## Verification and external prerequisites
58+
59+
- SDK update passed full `npm run verify`, eight GJC E2Es, credentialed response/
60+
abort smoke, and Node 22/24 CI before #30 merged.
61+
- Latest #38 source passed Node 22/24 CI, Linux package build and package/GUI
62+
checks on both Ubuntu versions before merge.
63+
- Full integrated `npm run verify` passed at `a69facd` and again at `b07394c`,
64+
including the cleanup-reaping correction. The initial CI failure came from
65+
expensive DOM-object assertion formatting in focus waits; boolean assertions
66+
preserved behavior coverage without raising the timeout.
67+
- Node 22/24 and all Linux package/GUI checks passed on `b07394c`. Final-head
68+
CI disposition is recorded on PR #39.
69+
- Final GJC/browser/clone/native E2E invocation passed 17 tests without skips;
70+
native integration tests in the full gate cover the remaining test suites.
71+
- Real browser acceptance created a managed worktree, wrote only its proof
72+
file, retained the original project binding after reload, completed a second
73+
read-only goal in the same worktree, and cancelled an approved running wait.
74+
The native job returned to ready with its lease cleared and an `aborted`
75+
terminal in replay. The REST replay helper was corrected to `/events`.
76+
- The Developer ID-signed macOS candidate built from `b07394c` (identical tree
77+
`c6a91510690f043e9ed51790e064ef6833d5d197`) passed strict signatures, 7/7
78+
out-of-tree packaged checks and the separate data-survival smoke. No new
79+
notarization or release publication was performed.
80+
- GitHub-hosted signing still needs `APPLE_CERTIFICATE_P12`,
81+
`APPLE_CERTIFICATE_PASSWORD`, `APPLE_ID`, `APPLE_TEAM_ID` and
82+
`APPLE_APP_PASSWORD`. Local identity/profile readiness does not configure CI.
83+
- Windows execution and full interactive GNOME/KDE sessions are not claimed.
84+
Conversation forks and split panes remain separately deferred product scope.
85+
- Fresh macOS GUI acceptance requires a disposable macOS account: existing
86+
environment overrides do not isolate the WebKit data store. Browser UI and
87+
package/signature checks are separate evidence.
88+
- Issue #3 remains open for the original Cursor/Anthropic live qualification
89+
and native skill/CLI efficiency. The requested Astra-only lane now completes
90+
the bundled workflows; it does not establish those other-provider results or
91+
eliminate their large workflow/receipt overhead.
92+
93+
Local evidence during this run is under `/tmp/gajae-followups-e2e/`; the final
94+
report records results so it does not depend on temporary credentials or live
95+
test processes remaining on disk.

0 commit comments

Comments
 (0)