Skip to content

feat(autoresearch)!: replace the team workflow with a first-class autoresearch skill - #4430

Open
Yeachan-Heo wants to merge 29 commits into
devfrom
feat/deprecate-team-skill-and-add-autoresearch-goal-skill
Open

feat(autoresearch)!: replace the team workflow with a first-class autoresearch skill#4430
Yeachan-Heo wants to merge 29 commits into
devfrom
feat/deprecate-team-skill-and-add-autoresearch-goal-skill

Conversation

@Yeachan-Heo

@Yeachan-Heo Yeachan-Heo commented Aug 13, 2026

Copy link
Copy Markdown
Owner

gajae.pr-review-verdict.v1 merge-blocked sha256:f18a34de4cfb4745ff6baa2e877673f98f0eda6494dbcfa0e63f94b53601ac99 reviewer:human reviewer-id:Yeachan-Heo evidence:Exact head 95a40f6 is rebased on origin/dev 91a3511. Retired bundled Team definitions now fail defaults checks; exact-head CI and independent approval are pending. Owner-authorized DRAFT HOLD.

@Yeachan-Heo
Yeachan-Heo force-pushed the feat/deprecate-team-skill-and-add-autoresearch-goal-skill branch from 4dea445 to 0a08258 Compare August 13, 2026 04:20
@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

The reported evidence-producer failure belonged to superseded head 4dea4456c493471c5b9d996b57b5a73e46a8af86: plan rejected missing immutable base ancestry, so no plan artifact existed downstream. The branch has already been force-rebased to exact head 0a08258418138ee0cd8b29c1178bd1ba45b196cd, which contains current dev@628604d5b67e8af376d31667a14b1c13f281e183; new exact-head CI run 31666736212 is active.

A dedicated Kimi adversarial review lane is active with accepted turn 13593fe1-07f7-42e2-9cd6-cdc22e8496bb, covering capability parity, breaking workflow migration, state/write durability, kernel teardown, branch isolation, computer safety, generated artifact policy, and stale team/rlm surfaces. It will post a terminal GitHub verdict and fix-forward the existing branch before merge/close.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4dea4456c4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


### Phase 2 — iterate

Iterate experiments on an `autoresearch/*` branch with baseline/keep/discard discipline. Log every run: `keep` when the primary metric improves, `discard` when it regresses or stays flat, `crash` when the run fails, `checks_failed` when validation fails. A `keep` commits the run only on the dedicated branch; `discard`/`crash`/`checks_failed` revert it. Flag suspect runs (reward-hacked, invalid, unjustified) so they are excluded from baseline and best-metric math. When the worktree is too dirty to branch, the loop degrades to off-branch mode: keeps stay in the worktree, and discards revert only run-modified paths so pre-existing user dirt survives.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep autoresearch from committing implementation changes

For experiments that require changing project code, this phase explicitly commits improved edits—or leaves them in the user's worktree when branch isolation is unavailable—so invoking the research-only workflow performs implementation without approval. Remove code-changing iteration from this skill or route it through the normal approval-gated execution path.

AGENTS.md reference: AGENTS.md:L100-L106

Useful? React with 👍 / 👎.

: renderHandoffIntakeText(receipt),
};
}
const goal = extractPositionalGoal(args);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Dispatch autoresearch verbs before treating arguments as a goal

Every non---spec invocation is routed through cold intake, so the documented gjc autoresearch read --json returns a clarification receipt with goal read, while gjc autoresearch clear does not clear anything. Cold intake also has no reachable write verb after clarification, leaving it unable to create the mission required by the Python tool; dispatch read, write, and clear explicitly before parsing positional goal text.

Useful? React with 👍 / 👎.

Comment on lines +250 to +255
const receipt = await autoresearchRead(input.cwd, input.getSessionId());
if (!receipt.exists || !receipt.mission) return null;
const { writer } = await openMissionNotebook(input.cwd, receipt.mission);
return {
missionId: receipt.mission.slug,
artifactsDir: missionArtifactsDir(input.cwd, receipt.mission),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Thread the live session ID into notebook path resolution

In a normal direct AgentSession launch, getSessionId() supplies the mission reader with the correct session while GJC_SESSION_ID is unset; openMissionNotebook and missionArtifactsDir then discard that ID and eventually call resolveGjcSessionForWrite using only the environment, which throws missing_for_write. Consequently the discoverable Python tool reports unreadable mission state instead of executing for ordinary sessions; pass the resolved session ID through the notebook/artifact helpers.

Useful? React with 👍 / 👎.

Comment on lines +246 to +249
const [{ autoresearchRead }, { openMissionNotebook, missionArtifactsDir }] = await Promise.all([
import("../gjc-runtime/autoresearch-runtime"),
import("./session"),
]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Move mission resolver dependencies to top-level imports

The live Python tool performs two inline import() calls on every mission-context resolution, contrary to the repository's top-level-import-only convention. Move these dependencies to top-level imports, extracting the mission reader into a cycle-neutral module if necessary.

AGENTS.md reference: AGENTS.md:L111-L114

Useful? React with 👍 / 👎.

Comment on lines +30 to +33
beforeAll(() => {
previousGjcSessionId = process.env.GJC_SESSION_ID;
process.env.GJC_SESSION_ID = TEST_SESSION_ID;
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Scope the session environment mutation to individual tests

This suite pins process.env.GJC_SESSION_ID for its entire lifetime, so sibling tests sharing the Bun process can resolve state against test-session instead of exercising missing/explicit session behavior; this can both make results order-dependent and mask the notebook session-propagation failure. Pass session IDs explicitly or use a per-test scoped mutation with immediate cleanup.

AGENTS.md reference: AGENTS.md:L154-L158

Useful? React with 👍 / 👎.

@Yeachan-Heo
Yeachan-Heo force-pushed the feat/deprecate-team-skill-and-add-autoresearch-goal-skill branch from 3fd57b0 to 6529879 Compare August 13, 2026 04:53

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6529879215

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

d. Persist the reconciliation with `gjc ralplan --write --stage post-interview --stage_n <N> --artifact-env GJC_RALPLAN_ARTIFACT --json`, then return the receipt/path plus a compact status (reconciled-clean / reconciled-with-revision / open-confirmations-pending) instead of pasting the full body.
7. On reconciliation completion, re-check the review join gate (Critic `OKAY` plus Architect `CLEAR`/`APPROVE` for the same Planner artifact/pass), mark the plan `pending approval` unless execution is already authorized by the resolved handoff admission, then persist the ADR/final plan via `gjc ralplan --write --stage final --stage_n <N> --artifact-env GJC_RALPLAN_ARTIFACT --json`. Read the successful receipt's `auto_handoff` object; its ledger-backed `effectiveTarget` is runtime-owned and is the only automatic-routing decision; do not directly edit `.gjc/_session-{sessionid}/plans`. Final plan must include ADR (Decision, Drivers, Alternatives considered, Why chosen, Consequences, Follow-ups) and, when present, the **## Intent Reconciliation** section.
8. **Final admission and approval gate:** Reconciliation must first reach the successful final receipt from step 7. If that receipt has `auto_handoff.degradationReason: "planning_stuck"`, it is terminal: retain the `pending approval` artifact and **never dispatch**, including for an explicitly named execution skill; do not issue an approval `ask`. Otherwise, if its runtime-owned `auto_handoff.effectiveTarget` is `ultragoal` or `team`, that valid non-off receipt is explicit operator admission for same-turn execution through that target; proceed to step 9 without an `ask`. If it is `off`, including ordinary `off` or a runtime degradation such as `team_unavailable:<reason>`, preserve the ordinary approval flow: if the user already explicitly named an execution skill in the current turn or via the structured approval UI (`ultragoal`, `/skill:ultragoal`, `gjc ultragoal`, `team`, `/skill:team`, `gjc team`, or "Approve execution via ultragoal/team"), that is execution approval — skip the re-ask and proceed to step 9 with that skill. Otherwise, present the finalized plan via the `ask` tool (regardless of `--interactive`) with `workflowGate: { stage: "ralplan", kind: "approval" }` on the final question so RPC/headless clients receive a `ralplan`/`approval` workflow gate, not a deep-interview question gate. Use these options:
8. **Final admission and approval gate:** Reconciliation must first reach the successful final receipt from step 7. If that receipt has `auto_handoff.degradationReason: "planning_stuck"`, it is terminal: retain the `pending approval` artifact and **never dispatch**, including for an explicitly named execution skill; do not issue an approval `ask`. Otherwise, if its runtime-owned `auto_handoff.effectiveTarget` is `ultragoal`, that valid non-off receipt is explicit operator admission for same-turn execution through that target; proceed to step 9 without an `ask`. If it is `off`, including ordinary `off`, preserve the ordinary approval flow: if the user already explicitly named an execution skill in the current turn or via the structured approval UI (`ultragoal`, `/skill:ultragoal`, `gjc ultragoal`, or "Approve execution via ultragoal"), that is execution approval — skip the re-ask and proceed to step 9 with that skill. Otherwise, present the finalized plan via the `ask` tool (regardless of `--interactive`) with `workflowGate: { stage: "ralplan", kind: "approval" }` on the final question so RPC/headless clients receive a `ralplan`/`approval` workflow gate, not a deep-interview question gate. Use these options:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Handle the autoresearch admission target

When gjc.ralplan.autoHandoff is configured as autoresearch, the runtime persists effectiveTarget: "autoresearch", but this gate handles only ultragoal and off; step 9 likewise invokes only ultragoal. That leaves an admitted plan with no defined continuation, so the documented automatic research handoff stalls instead of invoking /skill:autoresearch. Add an explicit autoresearch branch that performs the research-only handoff.

AGENTS.md reference: AGENTS.md:L100-L106

Useful? React with 👍 / 👎.

.replace(/[^A-Za-z0-9_-]+/g, "-")
.replace(/^-+|-+$/g, "")
.slice(0, 128);
return isValidRlmSessionId(sanitized) ? sanitized : generateRlmSessionId();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Make the fallback notebook identifier stable

For a valid cold-intake slug that sanitizes to nothing, such as a Unicode-only slug, this generates a new ID on every call. openMissionNotebook even calls this helper separately for the write path and the resume read, and later Python calls and report generation get still more IDs, so cells are never resumed and the final report can point at an empty notebook. Reject such slugs or derive one deterministic fallback from the persisted mission.

Useful? React with 👍 / 👎.

Comment on lines +434 to +437
const ledgerEvent = await appendAutoresearchLedger(
cwd,
{ event: "kernel_cleared", slug: existing?.slug ?? "" },
resolvedSessionId,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Actually dispose the kernel before recording it as cleared

Even after the separately reported CLI verb-dispatch problem is repaired, autoresearchClear only removes mission.json and appends kernel_cleared; it never calls disposeKernelSessionsByOwner for autoresearch:<slug>. If another mission with the same slug is created in the same agent session, the Python tool reconnects to the old live kernel and exposes variables/imports from the supposedly cleared mission. Dispose the existing mission owner before emitting this ledger event.

Useful? React with 👍 / 👎.

if (!mission) throw new AutoresearchCommandError(2, "autoresearch report requires an active mission");
const { writer, paths } = await openMissionNotebook(cwd, mission);
const ledger = await readAutoresearchLedger(cwd, sessionId);
const verdict = extractVerdictFromLedger(ledger);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Select the verdict for the current mission

The session ledger is intentionally retained across clear and subsequent mission creation, but report generation takes the latest verdict in the entire ledger without checking its slug. If mission A issues a verdict, is cleared, and mission B is started without a verdict yet, mission B's report embeds mission A's verdict and evidence. Filter ledger events by the active mission slug before selecting the latest receipt.

Useful? React with 👍 / 👎.

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

CI status: all remaining failures are pre-existing on dev

This PR introduces zero test or gate failures. Every red check reproduces on a clean checkout of origin/dev with no changes from this branch applied.

Verified by adding a detached worktree at origin/dev and running each failing job's command there:

git worktree add --detach /tmp/devcheck origin/dev
cd /tmp/devcheck
env -u GJC_SESSION_ID bun test packages/coding-agent/test/sdk-memory-startup.test.ts   # 0 pass, 1 fail
env -u GJC_SESSION_ID bun test packages/coding-agent/test/agent-session-message-pipeline.test.ts  # 1 fail
bun run --cwd=packages/coding-agent check                                              # FAIL
bun run check:tools                                                                    # FAIL
Failing check Cause On clean dev?
check:@gajae-code/coding-agent lint errors in src/sdk/bus/index.ts, src/sdk/bus/telegram-daemon.ts, src/sdk/host/session-runtime.ts, src/session/session-manager.ts, src/config/settings.ts — none touched here ❌ fails
root-check same, via check:toolsci:check:full ❌ fails
test:…/agent-session-message-pipeline.test.ts forwards stop reasons and reasoning summaries to extension handlers ❌ fails
test:…:shard-1-of-8 contains the two dev tests above (sdk-memory-startup, agent-session-message-pipeline) ❌ fails
evidence producer fails closed because required shards above failed cascade
Affected path validation aggregate of the above cascade

Deliberately not fixed here: they are unrelated to retiring team/rlm and belong in their own PR, per the repo's one-logical-change-per-commit rule. Bundling SDK/session lint and two SDK test regressions into a 21-commit breaking-change PR would make this much harder to review.

What this PR's own surface does

Everything owned by this change is green:

  • Local public surfaces
  • gjc-state-gates / static, / read, / integrity
  • all test:packages/coding-agent/test/autoresearch/* shards ✅
  • test:…/default-gjc-definitions.test.ts, cli-command-surface, gjc-skill-state-hooks, workflow-hud-summary, skill-active-state*, workflow-state-command, generate-gjc-sdk-skills
  • packages/tui autocomplete + editor-autocomplete-actions ✅
  • ts-build for coding-agent and stats

Two of my own breakages that CI legitimately caught

Both are fixed in this branch, and both are worth noting because a green local run hid them:

  1. customize CLI commanddev registered a new command while this branch was in review. cli-command-surface asserts the registered list in registration order, so it failed on both membership and position. Fixed by inserting it at its real position.

  2. Ambient GJC_SESSION_IDtest/autoresearch/session.test.ts and test/autoresearch/python-tool-builtin.test.ts read the session id from the environment. They passed locally only because they were authored inside a live GJC session where that variable is set; on a clean runner the mission resolver raised SessionResolutionError, which the python tool's fail-closed catch surfaced as an error result. Both now pin the id in beforeAll and restore it in afterAll, matching the existing pattern in runs/report/capabilities. Reproduced before the fix and verified after with env -u GJC_SESSION_ID.

The second one is the more interesting failure: the tool behaved correctly — it failed closed rather than starting an ad-hoc kernel — and the test was what was wrong.

@Yeachan-Heo
Yeachan-Heo force-pushed the feat/deprecate-team-skill-and-add-autoresearch-goal-skill branch from 6529879 to a58dd4b Compare August 13, 2026 05:24

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a58dd4b0a0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +173 to +174
const ownerId = autoresearchKernelOwnerId(missionContext.missionId);
seenOwnerIds.add(ownerId);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Namespace mission kernels by live session

When two live AgentSessions in the same process run missions with the same slug, this derives the identical autoresearch:<slug> owner and passes it as the executor session ID. The executor keeps a process-global map keyed only by that ID, so the second mission reuses the first mission's Python process, exposing variables and loaded data across sessions; clearing or disposing either mission can also terminate the other's kernel. Include the GJC session identity—and ideally the project identity—in the kernel session/owner key.

Useful? React with 👍 / 👎.

Comment on lines +798 to +800
3. **Continue research with autoresearch (research continuation, not execution)**
- Description: "Feed the crystallized spec into an autoresearch mission to deepen research grounding before any implementation planning. This is not an execution path and implements nothing."
- Action: Invoke `/skill:autoresearch` with the spec file path as context only after the user explicitly selects this option. The crystallized spec seeds the research mission, which then feeds the productification interview before any ralplan/ultragoal planning, per the chain deep-interview → autoresearch → productification interview → ralplan/ultragoal. Do not treat this as an execution handoff: no implementation happens here.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Make deep-interview emit a valid autoresearch handoff

When the user selects this new continuation, the instruction passes the spec path merely "as context," although autoresearch recognizes a handoff only through --spec; even if the agent translates it to --spec, the canonical deep-interview spec template never emits the required autoresearch-mode: declaration, so parseAutoresearchSpec rejects it. Collect and persist the mode in the spec and invoke /skill:autoresearch --spec <path> so the advertised deep-interview → autoresearch flow can actually start.

AGENTS.md reference: AGENTS.md:L107-L107

Useful? React with 👍 / 👎.

Comment thread README.md
| `ralplan` | Builds and critiques the implementation plan before code changes. |
| `ultragoal` | Tracks goals through execution, revision, verification, and evidence. |
| `team` | Coordinates tmux-backed workers when parallelism is worth it. |
| `autoresearch` | Runs goal-directed research missions and ends on a structured verdict. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Sync localized READMEs with the removed command surface

The English README now advertises the replacement surface, but README.ja.md, README.ko.md, and README.zh-CN.md still list team as the fourth default workflow and direct users to the removed gjc rlm command and gjc_delegate_team MCP tool. Users following any localized README therefore receive nonexistent-command/tool failures; update those copies alongside this surface replacement.

AGENTS.md reference: AGENTS.md:L102-L106

Useful? React with 👍 / 👎.

@Yeachan-Heo
Yeachan-Heo force-pushed the feat/deprecate-team-skill-and-add-autoresearch-goal-skill branch from a58dd4b to a13dd22 Compare August 13, 2026 06:35

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a13dd22452

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +893 to +895
export async function autoresearchRunsStore(cwd: string, sessionId?: string | null): Promise<AutoresearchRunsStore> {
const store = await AutoresearchRunsStore.open(cwd, sessionId);
if (store.config === null) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Namespace run records by active mission

When mission A is cleared and mission B is created in the same GJC session, AutoresearchRunsStore.open reopens the same session-wide runs.jsonl and experiment.json; this branch only seeds B when no config exists and never checks the stored config's name against B's slug. As a result, B's dashboard and iterate prompt can use A's goal, metrics, and logged runs, corrupting the new mission's experimental baseline. Key run storage by mission slug or reset it as part of mission replacement.

Useful? React with 👍 / 👎.

Comment on lines +517 to +519
const h1 = lines.find(line => /^#\s+\S/.test(line.trim()));
const objective =
(h1 ?? lines.find(line => line.trim() !== ""))?.trim().replace(/^#\s+/, "") ?? path.basename(specPath);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Read the canonical Goal section for handoff objectives

For a spec emitted by the bundled deep-interview template, the H1 is # Deep Interview Spec: {title} while the crystallized objective is under ## Goal; this parser always selects the H1, so the autoresearch mission and its experiment prompts receive the wrapper title instead of the detailed goal. Parse the canonical Goal section first and add a fixture using the actual bundled spec format.

AGENTS.md reference: AGENTS.md:L107-L107

Useful? React with 👍 / 👎.

import { BUNDLED_GJC_SKILL_CATALOG, type BundledGjcSkillCatalogEntry } from "./gjc-skills.generated";

export const DEFAULT_GJC_DEFINITION_NAMES = ["deep-interview", "ralplan", "team", "ultragoal"] as const;
export const DEFAULT_GJC_DEFINITION_NAMES = ["autoresearch", "deep-interview", "ralplan", "ultragoal"] as const;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update the discovery prompt with the canonical workflow set

After replacing team here, the live packages/coding-agent/src/prompts/tools/skill-discovery.md instruction and its generated tool-catalog description still tell the model that team is bundled and omit autoresearch. A session using skill discovery can therefore attempt the removed workflow despite the runtime catalog exposing the opposite set; update the source prompt and regenerate the catalog with this canonical-list change.

AGENTS.md reference: AGENTS.md:L102-L102

Useful? React with 👍 / 👎.

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

CI update — 84 pass / 5 fail, all 5 inherited from dev

Also a correction to my earlier CI comment: that attribution was measured in a git worktree that had no node_modules, so some of what I reported as "fails on clean dev" was really just unresolved imports. The method was wrong even where the conclusion happened to be right. Re-verified below with a method that holds up.

Two failures I owned, now fixed

  • check:@gajae-code/coding-agent / root-check — the one real error was an organizeImports violation in src/autoresearch/python-tool.ts, introduced when I moved the tool description into a static .md. Fixed; both jobs are green.
  • Earlier: ambient GJC_SESSION_ID and dev's new customize command (described in the previous comment).

The remaining 5, and how each was verified

Verified in this working tree — same node_modules, same linked workspace packages — by checking out dev's exact version of the relevant files, running, then restoring. No cross-worktree resolution involved:

Failing check Verification Result
test:…/config/settings-workflow-migration.test.ts git checkout origin/dev -- <that test> <src/config/settings-schema.ts> then run 78 pass / 43 fail — byte-identical to this branch's 78/43, so the suite is broken on dev independent of my change. My only edit to it swaps one autoHandoff fixture value from "team" to "ultragoal", since team no longer validates. The failures are all maxIterations Expected: 9 / Received: 7 on backup/abort paths, unrelated to autoHandoff.
test:…/agent-session-message-pipeline.test.ts run at this HEAD fails on forwards stop reasons and reasoning summaries to extension handlers; file untouched by this branch
test:…:shard-1-of-8 dev's own dev-ci run (31671259990) this shard is failure on dev itself — it contains the two tests above
evidence producer fails closed because the shards above failed
Affected path validation aggregate of the above

Note on why settings-workflow-migration appears here but not on dev's runs: it enters the affected set only because this PR touches src/config/settings-schema.ts (one enum value for autoHandoff). dev doesn't touch that file, so its own path selection never schedules the suite — which is how a broken suite stayed invisible.

This PR's own surface

Green, including everything added or changed here:

  • all test/autoresearch/* shards, the mission runtime, agent-session-signal-teardown
  • default-gjc-definitions, cli-command-surface, gjc-skill-state-hooks, workflow-*, skill-active-state*
  • computer.enforcement + computer.redteam, descriptors
  • gjc-state-gates (static / read / integrity / runtime), Local public surfaces
  • packages/tui autocomplete + editor-autocomplete-actions
  • ts-build for coding-agent and stats

Locally at this HEAD: 209 tests pass / 0 fail across the autoresearch suites, mission runtime, signal-teardown, default-gjc-definitions, cli-command-surface, the descriptor registry and both computer suites; check:types and check:tools both pass, with every remaining biome warning in a dev-only file.

Latest commit — documentation and runtime guidance

a13dd22452 closes three gaps where the shipped behavior had no matching guidance:

  • src/prompts/tools/python.md (new) — the tool now imports its model-facing description with { type: "text" } instead of an inline string. Every other builtin already keeps its prompt there and AGENTS.md forbids inline prompts; this tool was the lone exception.
  • docs/tools/python.md (new) — matches the sibling per-tool docs: discoverable/defaultInactive registration and why activation must pass the full merged tool list, execute/clear with no separate teardown tool, per-call mission resolution, and the fail-closed contract that a missing or corrupt mission never degrades to an ad-hoc kernel.
  • docs/python-repl.md — new Kernel ownership section separating session-owned kernels (eval) from explicitly-owned ones (autoresearch:<mission-id>), and recording that signal exit drains both tool-cleanup registries. That last detail is the Ctrl-C orphan bug: the SDK puts a tool's registerSessionCleanup in the transition registry, so draining only the session registry left the kernel running while graceful dispose looked correct.
  • docs/tools/eval.md — cross-reference so the two Python-running tools aren't confused.

Every claim in those docs was read back out of the shipped code, and the regenerated tool catalog and docs index both carry the new description.

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Fresh terminal evidence — rebased exact head

  • head: 8727e0f85478895ead3329e79585afb1da240de2
  • base: 6080b98310038b963479fdc8a499dc326c81fe86 (dev)
  • The branch was force-with-lease rebased from the historical PR base to the exact current dev base; git merge-base origin/dev HEAD is the base above and git diff --check origin/dev...HEAD is clean.
  • Intended breaking replacement remains intact: canonical workflows are autoresearch, deep-interview, ralplan, ultragoal; team and rlm public/runtime surfaces are removed, and autoresearch CLI/runtime/skill/docs/generated catalogs are present.
  • Local proof at this exact head: bun --cwd=packages/coding-agent run build passed; autoresearch runtime/signal suites 116 pass; pipeline 23 pass; CLI/state/help suites 94 pass; computer safety/descriptors suites 41 pass; plugin/sdk-skill/schema/docs generation checks pass.
  • settings-workflow-migration is byte-identical to current dev except the required teamultragoal expected value. It fails 78 pass / 43 fail on both this exact head and a separately installed, native-built origin/dev@6080b98310038b963479fdc8a499dc326c81fe86; the test harness inherits GJC_CODING_AGENT_DIR / PI_CODING_AGENT_DIR while setting only HOME/GJC_CONFIG_DIR, so its synthetic-home probes are contaminated. This is baseline/environmental, not PR-owned.
  • Fresh process shard 1 likewise has inherited baseline failures beyond the prior PR CI: migration, PI_CONFIG_DIR, session lock, and LSP regressions; the PR-owned autoresearch and CLI surfaces passed.

Please perform a fresh adversarial review against this exact head/base and post a signed terminal MERGE_READY or CLOSE verdict. Do not rely on earlier reviews of superseded heads.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

@codex review

Review target: head 8727e0f85478895ead3329e79585afb1da240de2, base 6080b98310038b963479fdc8a499dc326c81fe86.


[repo owner’s gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Signed terminal verdict: CLOSE — replacement is not mergeable

  • head reviewed: 8727e0f85478895ead3329e79585afb1da240de2
  • base reviewed: 6080b98310038b963479fdc8a499dc326c81fe86 (dev)
  • verdict: CLOSE (fresh adversarial review found blocking product-contract and durable-runtime defects; not a stale-CI attribution close).

Fresh read-only adversarial audit found the intended Team → Autoresearch replacement incomplete and internally contradictory:

  1. gjc autoresearch read --json and gjc autoresearch clear are documented public commands but runNativeAutoresearchCommand dispatches neither; both are treated as successful cold-intake text. The mission/ledger cannot be read or cleared through the shipped CLI.
  2. Run logging, verdict/critic receipts, report synthesis, and experiment lifecycle are exposed only as direct helper APIs, not an authoritative public command workflow.
  3. The canonical skill says Autoresearch is research-only and never modifies product code, while active phase prompts authorize arbitrary source/manifests/binary edits without an approval or isolation boundary.
  4. Mission slugs accept punctuation-only values, causing a nondeterministic random artifact identity on reopen; state/HUD sync writes unsupported mission instead of a manifest phase; clear does not dispose a live Python kernel.
  5. Live closure remains stale: gjc state help advertises team; docs/skills.md, skill-discovery prompt/catalog, bundled cleaner/planner guidance, and Unreleased changelog are incomplete; dashboard best selection fails to exclude flagged runs.

The preserved prior-worktree generated catalog delta is unrelated (task-agent wording only) and was not incorporated. Local focused proof did pass autoresearch/unit, pipeline, CLI/help, computer-safety, generation, and binary-build checks; that proof is insufficient to override the missing/contradictory public lifecycle.

The migration and pipeline CI failures were independently attributed to current-dev baseline/environmental defects, but the blocking findings above are PR-owned. Repair requires a newly scoped, coherent Autoresearch lifecycle and policy design rather than further patching this 18-commit replacement branch.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Closing against exact head 8727e0f85478895ead3329e79585afb1da240de2 and base 6080b98310038b963479fdc8a499dc326c81fe86: signed terminal verdict is CLOSE; see the immediately preceding adversarial evidence comment.


[repo owner’s gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Terminal ownership resumed on authoritative immutable refs

  • head: 8727e0f85478895ead3329e79585afb1da240de2
  • base: 6080b98310038b963479fdc8a499dc326c81fe86 (dev)
  • git fetch, git ls-remote, and the Pull Request REST API now agree on these refs; local ↔ remote head is 0/0, and dev...head is 0 behind / 18 ahead.
  • No force-push was performed: the remote branch already equals the exact local head.

Reopened strictly for exact-head verification and a fresh terminal review. The PR will be merged only on green CI plus a clean MERGE_READY verdict; otherwise it will be signed-closed without OPEN limbo.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo Yeachan-Heo reopened this Aug 13, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8727e0f854

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +425 to +426
await git.reset(input.cwd, { hard: true, target: "HEAD" });
await git.clean(input.cwd);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve pre-run changes when discarding on a mission branch

When a mission is resumed while already on an autoresearch/* branch, ensureAutoresearchBranch accepts the branch before checking whether it contains dirty files, but this discard path ignores preRunDirtyPaths and destroys the whole working tree. The local git reset -h states that --hard resets the index and working tree, and the git.clean wrapper invokes git clean -fd, forcibly removing untracked files and directories, so unrelated user work created before the run is lost. Apply the same run-modified-path filtering used by the off-branch path, or reject a dirty mission branch before starting.

AGENTS.md reference: AGENTS.md:L108-L108

Useful? React with 👍 / 👎.

cwd,
skill: "autoresearch",
active: true,
phase: "mission",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Persist a recognized active phase for autoresearch missions

When a --spec mission reaches context compaction, this records phase mission, which is absent from the autoresearch manifest (intake, research, verdict, etc.). isWorkflowContinuationInert deliberately treats unknown phases as inert, and AgentSession.#hasUnfinishedWork consequently does not schedule continuation for this otherwise-active mission, so research can stop after compaction until the user intervenes. Persist the manifest's active research phase instead.

Useful? React with 👍 / 👎.

@Yeachan-Heo
Yeachan-Heo force-pushed the feat/deprecate-team-skill-and-add-autoresearch-goal-skill branch from 8727e0f to e14ce82 Compare August 13, 2026 11:44
@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Exact-head repair and baseline evidence

  • head: e14ce829e83a35c8eb0019f92ba427d88d39142e
  • base: 0cecbaf819727d2c519ccf33974768058548ab61 (dev)
  • Branch was rebased once onto current dev and pushed with a lease. git merge-base origin/dev HEAD equals the base; git diff --check origin/dev...HEAD is clean.

This head repairs the PR-owned Autoresearch blockers: explicit public write, read, clear, log-run, critic, verdict, and report lifecycle verbs; safe stable mission artifact identity; live-kernel disposal and terminal active-state cleanup; flagged-run dashboard exclusion; research-only prompt/skill enforcement; stale Team references removed from state help, discovery, bundled guidance, docs, changelog, and regenerated tool catalog.

Exact local proof at this head:

  • bun --cwd=packages/coding-agent run check and bun --cwd=packages/coding-agent run build passed.
  • 217 focused autoresearch/default-definition/CLI/skill-state/catalog tests, plus 54 pipeline/signal/computer-redteam tests, passed.
  • End-to-end fresh CLI replay passed: spec handoff → log-runcriticverdictreportreadclear under a dedicated session.

Current exact-head Dev CI is 31696812425; its old CI predecessor is not authoritative.

Baseline evidence for the superseded CI red jobs: a self-contained /tmp/pr4430-current-dev checkout at origin/dev@0cecbaf819727d2c519ccf33974768058548ab61, with its own bun install --frozen-lockfile and native build, reproduces the same settings migration failure class. settings.ts, pi-config-dir.test.ts, and utils/dirs.ts are byte-identical versus this PR; only the required autoHandoff test fixture moves team to ultragoal. The former generated test/mcp-test-utils.d.ts root-check failure belongs to the superseded CI environment and is absent from this clean tree.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

@codex review

Fresh adversarial review requested for exact head e14ce829e83a35c8eb0019f92ba427d88d39142e against base 0cecbaf819727d2c519ccf33974768058548ab61.

The prior lifecycle/closure blockers were repaired and evidence is in the preceding signed comment. Review only this immutable pair; do not rely on verdicts for superseded heads.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e14ce829e8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1082 to +1084
const branch = await ensureAutoresearchBranch(cwd, mission.objective).then(result =>
result.ok ? result.branchName : null,
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid switching branches while rendering research state

When a clean Git worktree has an active mission but no persisted experiment config, merely opening the dashboard or rendering the iteration prompt reaches this call, and ensureAutoresearchBranch executes a new-branch checkout. This silently changes the user's current branch during an otherwise read-only operation, despite the revised workflow promising that autoresearch does not create branches; seed the in-memory config without mutating Git state.

AGENTS.md reference: AGENTS.md:L108-L108

Useful? React with 👍 / 👎.

}
if (verb === "report") {
assertOnlyAutoresearchFlags(args.slice(1), ["--summary", "--json"]);
const reportPath = await autoresearchMissionReport(cwd, flagValue(args, "--summary"));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Return the actual report path from the report verb

autoresearchMissionReport returns the synthesized Markdown report text, not a pathname, so every gjc autoresearch report invocation assigns the full report body to reportPath and emits it under report_path. Human output becomes a multiline pseudo-path and JSON automation cannot locate the report file; return paths.reportPath from this command or return content and path separately.

Useful? React with 👍 / 👎.

Comment on lines +701 to +705
await appendAutoresearchLedger(
input.cwd,
{
event: "verdict_issued",
...(input.slug?.trim() ? { slug: input.slug.trim() } : {}),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Move issued verdicts into the verdict phase

After a mission issues its verdict, this only appends the ledger event and leaves the active workflow entry in research. If context compaction occurs before the subsequent clear, AgentSession.#hasUnfinishedWork treats that phase as active and schedules another continuation, whereas the manifest explicitly makes verdict continuation-inert; reconcile the active state to verdict after recording the receipt so a finished evidence loop does not restart.

Useful? React with 👍 / 👎.

slug: flagValue(args, "--slug"),
};
const receipt =
verb === "critic" ? await autoresearchRecordCritic(input) : await autoresearchIssueVerdict(input);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject lifecycle writes without an active mission

When a delayed or mistyped log-run, critic, or verdict command runs before intake or after clear, these public branches invoke appenders without checking for an active mission and still return success; the resulting unscoped events remain in the session ledger and can contaminate a later mission's history and report. Load the current mission first, reject when absent, and derive the event slug from that mission rather than accepting an optional arbitrary slug.

Useful? React with 👍 / 👎.

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Exact-head terminal repair evidence

  • head: cc08a533a9f9f42809a6edc680a4bdda6ea330fa
  • base: 0cecbaf819727d2c519ccf33974768058548ab61 (dev)
  • Forced update used a lease from e14ce829e83a35c8eb0019f92ba427d88d39142e; no generated test/mcp-test-utils.d.ts was committed.

The fresh terminal review blockers are repaired:

  • public log-run now persists runs.jsonl consumed by dashboard/prompt state and validates status;
  • verdicts bind the latest critic receipt, advance active state to verdict, and synthesized reports retain the critic section;
  • kernel owner and notebook/report/artifact paths are session-scoped and stable for same-slug concurrent missions;
  • opening dashboard state no longer creates/switches branches; the research-only contract is non-mutating;
  • controller documentation now satisfies the active external-controller contract; task catalog generation is isolated and excludes the noncanonical reviewer fixture entry.

Proof at this exact head: bun --cwd=packages/coding-agent run check and build passed; 279 focused autoresearch, lifecycle, definitions, CLI, controller-docs, catalog, pipeline, signal teardown, and computer red-team tests passed; fresh CLI replay passed spec handoff → run → critic → verdict → report → read → clear.

Exact-head Dev CI runs 31699588651 and 31699588693 are active. Do not use prior-head red results as this head's verdict.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo
Yeachan-Heo force-pushed the feat/deprecate-team-skill-and-add-autoresearch-goal-skill branch from cc08a53 to a66c1e1 Compare August 13, 2026 12:23
Yeachan-Heo and others added 27 commits August 17, 2026 18:48
Deleting only the team command would leave a public delegation path that
starts a session and prompts /skill:team for a skill that is about to stop
existing. The coordinator contract, the workflow unions that persist Codex
handoffs, and the generated plugin bundle all have to drop team together
or the protocol advertises a dead workflow.

Lore-id: c3f2e9b7
Constraint: generic coordinator/session/tmux plumbing stays -- only the
  team-specific delegate contract is removed
Constraint: the gjc_delegate_plan / gjc_delegate_execute round-trip pair
  must keep passing; that pair is the falsifiable AC-8b evidence
Rejected: remap gjc_delegate_team onto ultragoal | silently changes what a
  caller asked for, and the architect review called this out explicitly
Rejected: keep the tool and reject at call time | a shim by another name
Confidence: high
Scope-risk: moderate
Reversibility: easy
Directive: the delegate self-check count is load-bearing -- generate-gjc-plugins
  and verify-gjc-plugins both assert the exact delegate set, so they move with
  the contract
Tested: coordinator-mcp-server 92/92 (incl. the plan/execute lifecycle
  round-trip), coordinator-codex-bridge-redteam 7/7, setup-cli 18/18,
  generate-gjc-plugins --self-test, verify-gjc-plugins 16/16 gates,
  generate-gjc-plugins --check in sync; tsc and biome clean
Not-tested: verify-g002-gates -- pre-existing failure at base 4c16e70
The team surface is being replaced by autoresearch. Everything except the
canonical slot itself can go now: the command, the eight team-* runtime
modules, and every consumer that reached into them. Team stays canonical
and stays in the skills directory through this commit so all four-skill
gates remain green -- the slot swap is a separate atomic change.

Removing team-runtime orphaned WorkerIntegrationRequestScheduler, whose
only production caller was the team worker-integration flow but which is
independently covered by g004-redteam and agent-session-abort-timeout.
Rather than delete a red-team gate or leave a no-op fallback, the class
stays as a generic primitive and worker integration became an injected
seam: no scheduler is constructed unless a host supplies the request.

Lore-id: c4d1a8f3
Constraint: generic tmux-*.ts plumbing is untouched -- only team-owned
  modules and their consumers are removed
Constraint: autoHandoff lands the interim off|ultragoal enum here;
  autoresearch is added in the slot-swap commit, since admission has to
  dispatch a skill that actually resolves
Rejected: delete WorkerIntegrationRequestScheduler and its tests | weakens
  a G004 red-team gate to make a refactor pass
Rejected: keep the scheduler with a no-op default request | a fake fallback
  masquerading as a live path
Confidence: high
Scope-risk: wide
Reversibility: migration-needed
Directive: a stale `gjc.ralplan.autoHandoff: team` in a user config now
  exits 2 by design -- no coercion shim
Directive: shared red-team tests kept their harness_leases and file_locks
  assertions at full strength; only the team adapter rows were removed
Tested: 122 targeted tests green across default-gjc-definitions,
  cli-command-surface, cli-help-load-order, completion-cli,
  settings-workflow-migration, agent-session-message-pipeline,
  agent-session-state-aware-compaction, resource-gc-redteam, gc-redteam and
  g004-redteam; plus gc-runtime, resource-gc, ralplan-runtime,
  agent-session-abort-timeout and state-writer-drift. check-visible-definitions,
  verify-gjc-skill-docs, verify-gjc-plugins, rebrand-inventory --strict,
  tsc and biome all pass
Not-tested: verify-g002-gates -- pre-existing failure at base 4c16e70
disposeChildSubprocesses reaped only #evalKernelOwnerId, so a resource
registered through registerToolSessionCleanup under a different owner id
survived Ctrl-C. Until now nothing hit that gap in production because
`gjc rlm` reaped its own kernel in a command-level finally -- which C1
deleted. The autoresearch mission kernel uses a distinct owner id by
design, so without this the first signal exit orphans a Python
subprocess.

The drain reuses the existing #runToolSessionCleanups, which clears the
set as it runs, so graceful dispose and signal exit cannot double-free,
and it sits inside the existing Promise.race budget rather than adding a
second timer.

Lore-id: c5e3b7d2
Constraint: the mission owner id must stay distinct from the eval owner
  (spec f33), so aliasing the two was not an option
Rejected: a watchdog or orphan-reaper daemon | explicit non-goal, and a
  bounded drain on the path that already exists is enough
Confidence: high
Scope-risk: narrow
Reversibility: easy
Tested: agent-session-signal-teardown 8/8. The four new cases were proven
  fail-today by temporarily reverting the drain: all four failed, including
  the hang case which blew past the time box at 5059ms, then passed again
  once restored
First additive half of the rebuilt subsystem: a thin `gjc autoresearch`
command in the shape of `gjc ultragoal`, a runtime that owns the mission
artifact, the JSONL ledger, and verdict/critic receipts, and the
persistent Python tool the data lane runs on.

Mode is validated at the mission-write boundary and is never inferred --
a spec or invocation without an explicit web|mixed|data mode is rejected
even when a data file is sitting right there. Ledger and mission state
live under `.gjc/_session-{id}/autoresearch/`; nothing writes to the old
project-global `~/.gjc/autoresearch` store.

The python tool is registered at construction as a `defaultInactive`
ToolDefinition and activated by merging into the full active-tool list,
because `setActiveToolsByName` silently drops names it does not know and
`activateDiscoveredTools` only ever sees built-ins. Clearing the kernel
is an action on that same tool -- no second teardown tool -- and the
mission owner id stays distinct from the session eval owner.

Lore-id: c5a4f1b8
Constraint: purely additive -- no canonical list, skills directory, gate
  script, or settings schema is touched; the slot swap is still ahead
Constraint: verdict `status` stays structured data; pinning a terminality
  enum is deliberately deferred
Rejected: activateDiscoveredTools / loadMode "discoverable" | built-in
  discovery only, would have silently no-opped
Rejected: a separate clear/teardown tool | prohibited by AC-20
Confidence: medium
Scope-risk: moderate
Reversibility: easy
Directive: renamed the leaked `autoresearch/rlm/` path segment to
  `autoresearch/runs/` before it became a permanent layout
Tested: autoresearch-runtime 20/20 incl. mode-rejection, ledger ordering,
  verdict/critic round-trip and both handoff-intake paths; autoresearch
  python-tool suite; signal-teardown 8/8; cli-command-surface. tsc and
  biome clean, with biome verified against a stashed baseline so the one
  issue I introduced was found and fixed rather than absorbed
Not-tested: the eight retained capabilities and the bundled SKILL.md --
  they are the remaining half of this story
Completes the additive half of the subsystem under the zero-cut mandate:
every capability the deleted extension provided comes back, ported onto
session-scoped state instead of the project-global SQLite store.

Branch isolation keeps the reference's degraded path rather than the
happy path only: a dirty worktree off an autoresearch branch warns and
continues, and in that state keep skips auto-commit while discard reverts
only run-modified paths. Flagged runs stay excluded from baseline and
best-metric math. Data context is gated to explicit data/mixed mode, so
the no-inference rule holds at the consumption end and not just at the
mission write.

Lore-id: c5c9e2a6
Constraint: still additive -- no skills directory, canonical list, gate
  script, or settings schema is touched; the slot swap is the next commit
Constraint: no SQLite and no ~/.gjc/autoresearch; everything resolves
  under sessionAutoresearchDir
Confidence: medium
Scope-risk: moderate
Reversibility: easy
Directive: the two-phase prompts are static .md imported with
  { type: "text" }, scrubbed of the deleted /autoresearch command and the
  old global state paths
Tested: 99 tests green across the nine autoresearch suites plus the
  runtime suite, covering dirty-worktree degraded mode, METRIC/ASI parsing
  with malformed and interleaved lines, flagged-run exclusion, metric
  direction, data context refused in web mode, notebook cell per python
  call, and the verdict reaching the report. tsc and biome clean
Not-tested: end-to-end mission execution -- that needs the public skill,
  which lands with the slot swap
The exact-four-skill invariant is asserted across canonical lists, the
defaults catalog, four gate scripts, and their tests, so team leaves and
autoresearch arrives in one commit. Every intermediate ordering fails at
least one gate: deleting team/SKILL.md before the gate lists flip reports
a missing bundled skill, and adding autoresearch/SKILL.md first yields
five skill directories against a hard four.

Also lands the reconciled autoHandoff decision: the enum becomes
off|ultragoal|autoresearch so the freed slot is reachable by ralplan's
automatic admission. That value could not ship earlier, because admission
dispatches /skill:autoresearch and the skill only resolves now.

state-schema.ts previously duplicated the canonical list as its own
literal; it now imports the single source, so the four-skill set exists
in exactly one place and cannot drift.

BREAKING CHANGE: `gjc team`, `/skill:team`, and the team runtime are
gone. A stale `gjc.ralplan.autoHandoff: team` in a user config exits 2 by
design -- no coercion shim, per the no-back-compat rule.

Lore-id: c6f7b2e4
Constraint: this commit cannot be split; a transient three-skill state
  double-edits every gate and leaves a capability gap
Rejected: keep a team alias for one release | AGENTS.md forbids shims
Confidence: medium
Scope-risk: wide
Reversibility: migration-needed
Directive: generated artifacts are regenerated, never hand-edited --
  plugins, sdk-skills, schemas, docs-index and the workflow manifest all
  re-ran and are in sync
Tested: 123 tests green across default-gjc-definitions, gjc-skill-state-hooks,
  coordinator-codex-bridge-redteam, workflow-hud-summary and
  cli-command-surface, plus 125 across the TUI autocomplete/editor and
  input-controller suites. check-visible-definitions, verify-gjc-skill-docs,
  verify-gjc-plugins, verify-gjc-state-writers, rebrand-inventory --strict,
  tsc and biome (coding-agent + tui) all pass
Not-tested: verify-g002-gates still fails its MCP quarantine check --
  reproduced identically at the untouched base commit 4c16e70, so it is
  pre-existing branch breakage; its definition/skill checks now pass
… policy

Final verification fallout from the slot swap. `AGENTS_RETENTION` in the
workflow manifest had no consumer once the team manifest was replaced,
which biome flagged as a hard error rather than a warning. The rest is
formatter drift across files this branch touched.

Lore-id: c7d5a013
Confidence: high
Scope-risk: narrow
Reversibility: easy
Directive: formatting was applied only to files this branch changed
  against base 4c16e70, not repo-wide
Tested: check:tools passes; 316 tests green across the autoresearch
  suites, default-gjc-definitions, gjc-skill-state-hooks,
  cli-command-surface, agent-session-signal-teardown, g004-redteam,
  gc-redteam and coordinator-mcp-server
Not-tested: check:sdk-closure and verify-g002-gates still fail, both
  reproduced identically at the untouched base commit 4c16e70
  (agent_session:syncEagerDelegation pending seam; MCP quarantine)
… builtin

Boundary review caught that the mission python tool was defined but never
reachable: the old registration seam died with RlmPreset, and the thin
`gjc autoresearch` command never launches a session. The skill told the
model to use a `python` tool that was not in the registry, so AC-19's
activation half only ever held inside unit tests.

It is now a `loadMode: "discoverable"` builtin descriptor following the
`computer` precedent -- registered but inactive, activated on demand
through the discovery path, which is exactly the hidden-tool activation
the interview settled on. The tool resolves the active mission from
session state per call and fails closed with an actionable error when
none exists, rather than quietly starting a session-scoped kernel.

Also clears both cohort advisories: `src/rlm/preset.ts` plus its now
orphaned `rlm-research.md` prompt are deleted (the RlmPreset hook was
their only consumer, so commit 1c3c83b3f's promise that the retained
engine material would be consumed by the rebuild was not true for these
two), and a duplicated `#acquirePowerAssertion()` call is removed.

Lore-id: c7e8f4b1
Constraint: no silent fallback -- a missing mission must error, never
  degrade to an ad-hoc kernel
Constraint: kernel owner stays autoresearch:<mission-id>, distinct from
  the session eval owner
Rejected: register through options.customTools | no session-creation seam
  survives, and the thin command must not grow one
Confidence: high
Scope-risk: moderate
Reversibility: easy
Tested: 163 tests green across the autoresearch suites, the runtime suite,
  signal-teardown, the descriptor registry and default-gjc-definitions;
  new python-tool-builtin tests prove the descriptor is discoverable and
  inactive by default, that activation makes it callable, and that a
  no-mission call fails closed without starting a kernel. check:tools,
  check-visible-definitions, verify-gjc-skill-docs, verify-gjc-plugins and
  rebrand-inventory --strict all pass
The generation-1 teardown fix drained the wrong set for the consumer it
was written for. The SDK binds a tool's `registerSessionCleanup` to
registerToolSessionTransitionCleanup (sdk/session.ts:1925), so the
autoresearch mission kernel disposer lands in #toolSessionTransitionCleanups
-- while disposeChildSubprocesses drained only #toolSessionCleanups.
Graceful dispose drains both, so this was invisible there: Ctrl-C still
orphaned the mission kernel in production.

Every suite passed anyway, because the test registered through
registerToolSessionCleanup -- the set the drain already covered -- instead
of the production binding. The QA red-team lane caught it by tracing the
SDK binding rather than trusting the green run; the architect and cleaner
lanes both missed it.

Also makes a corrupt or unreadable mission fail closed the same way a
missing one does. It previously threw out of resolveMissionContext before
the null check, so the caller got an opaque throw instead of the
actionable message. No kernel started either way, but the boundary should
not leak.

Lore-id: c7f2d8a5
Constraint: no ad-hoc kernel on any failure path -- missing, corrupt, and
  unreadable mission state all return the same actionable error
Rejected: rebind registerSessionCleanup to the non-transition set | would
  change teardown semantics for every other tool that uses the SDK seam
Confidence: high
Scope-risk: narrow
Reversibility: easy
Directive: teardown tests must register through the production binding --
  a test that wires the drain's own set proves nothing about production
Tested: signal-teardown 11/11, and the three new cases proven fail-today
  by reverting the transition drain (all three failed, hang case blew the
  time box at 5052ms). 137 tests green across the autoresearch suites, the
  runtime suite, signal-teardown and the descriptor registry; check:tools
  and biome pass
The slot-swap commit claimed AC-27 but only updated system-prompt.md and
AGENTS.md; the terminal critic caught that five of the seven docs the plan
named still advertised retired surfaces. Removed the whole Team tmux
backend section from environment-variables.md (it documented eight
GJC_TEAM_* vars that no longer exist), the gjc_delegate_team references in
README.md and bot-integration.md, and the /skill:team mention in
analyze-me-with-gjc.md.

GJC_TEAM_TMUX_COMMAND was still honored as a live fallback alias in
psmux-detect.ts and described in tmux-common.ts, so the doc row was
accurate and the code was the thing out of date. Removed the alias and its
prose, leaving GJC_TMUX_COMMAND as the single override.

Lore-id: c7a9e6d3
Constraint: only team-named surfaces go; the generic tmux plumbing they
  lived in stays
Rejected: keep GJC_TEAM_TMUX_COMMAND as a silent alias | a compatibility
  shim for a command that no longer exists
Confidence: high
Scope-risk: narrow
Reversibility: easy
Tested: 226 tests green across psmux-detect, tmux-sessions, the
  autoresearch suites, the runtime suite, signal-teardown and
  default-gjc-definitions; types, check:tools, check-visible-definitions,
  verify-gjc-skill-docs, verify-gjc-plugins and rebrand-inventory --strict
  all pass. AC-27 sweep now returns zero live references to gjc team,
  /skill:team, gjc rlm, gjc_delegate_team or GJC_TEAM_* outside historical
  prompt-architect archives
The terminal critic caught that my previous sweep used too narrow a grep:
it matched `gjc team` and `/skill:team` but missed bare `team` in prose and
skill lists, so two docs the plan named were never touched and several
others still advertised a four-skill set containing team.

Fixed: codebase-overview.md (CLI command list, state categories),
onboarding-packet.md (workflow loop, default skill list, state
categories), gjc-plugins.md and ui-design-visual-qa.md (the exact-four
skill enumerations), gjc-dogfood-skill-template.md and
extragoal-skill-template.md (skill guidance and the nested-workflow
guard), install.md, analyze-me-with-gjc.md, bot-integration.md,
brand-assets.md, and the README skill table plus its workflow diagram.

Lore-id: c7b4f9c8
Constraint: dated records stay untouched -- CHANGELOG entries,
  docs/prompt-architect-reports/ audits, REBRANDING_PLAN and benchmark
  fixtures document past behavior and rewriting them would falsify history
Confidence: high
Scope-risk: narrow
Reversibility: easy
Directive: verify AC-27 with a pattern that catches bare `team`, not just
  the command forms -- the narrow grep is what let this through twice
Tested: 125 tests green across default-gjc-definitions, the autoresearch
  suites and signal-teardown; types, check:tools,
  check-visible-definitions, verify-gjc-skill-docs, verify-gjc-plugins and
  rebrand-inventory --strict all pass. The exhaustive sweep now returns
  only an asset filename and the word "gateways"
The terminal critic's OKAY listed one non-blocking polish item: the Windows
psmux troubleshooting note carried "team guarantees" twice on the same
line and the previous sweep fixed only the first. Shipping a known
residual after being told about it is not acceptable, so it goes now.

Lore-id: c7c1a2f6
Confidence: high
Scope-risk: narrow
Reversibility: easy
Tested: docs-index regenerated; docs/install.md now has zero team
  references
…ent probe

The mandatory computer-use red-team gate fires on any edit to
settings-schema.ts, and this branch edits it. That gate is not ceremony
here: settings-schema.ts defines the computer safety envelope itself
(computer.enabled, computer.alwaysOn, computer.killSwitchHotkey,
computer.auditLog.enabled, computer.screenshotMaxBytes,
computer.screenshotGc.*), so an edit there could weaken the kill switch.
Proving it did not is a real obligation, and it is satisfiable with real
tests rather than asserted away.

Running the repo's own seven-case probe surfaced a pre-existing failure:
permission-revoked has been failing at every commit, reproduced on a clean
worktree at base 4c16e70. The cause is not a safety defect. The
COMPUTER_PERMISSION_REQUIRED guidance was reworded to the more specific
"Grant Screen & System Audio Recording or Accessibility to the exact GJC
launcher..." wording, and the probe still asserted the old sentence
verbatim. The archived report at artifacts/vb001-gen5 still shows the old
message passing, which dates the drift. The probe now asserts the substance
of the contract -- the guidance must name Recording and Accessibility --
instead of one exact sentence, so a future rewording cannot silently break
it again while a dropped permission name still fails it.

The new suite covers all seven invariants against the real policy and
validation layers: enablement/kill-switch refusal, repeat-attempt
enforcement, mid-session revocation with no stale permission cache,
stale-display refusal and screenshot GC, pre-dispatch coordinate bounds
across click/double_click/move/drag-both-ends/scroll including edge and
negative values, bounded action sequences, and blast radius via screenshot
byte caps plus audit-record presence and absence. It also asserts each
computer safety key still exists in the registry with its expected type and
default -- the direct falsification test for the edit that triggered this
gate.

Lore-id: c8a3d7e2
Constraint: test-only; no computer source touched, and no real desktop
  input, pointer movement, or live screenshot is driven
Rejected: report permission-revoked as failed and escalate | the failure is
  a stale assertion, not a safety defect, and shipping a known-red probe
  hides real regressions
Rejected: mark the case not_applicable | the gate rejects that outright,
  and correctly
Confidence: high
Scope-risk: narrow
Reversibility: easy
Tested: 20 tests green across computer.enforcement and computer.redteam;
  the seven-case evidence report regenerates with all seven passed; types
  and biome clean. The pre-existing failure was isolated in a detached
  worktree at base to prove it predates this branch
Lore-id: c8d4a7f1
Confidence: high
Scope-risk: narrow
…the shell

Two suites depended on an ambient GJC_SESSION_ID and only passed because I
authored them inside a live GJC session, where that variable is set. On a
clean runner the mission resolver raised SessionResolutionError, which the
python tool's fail-closed catch reported as an error result -- so CI failed
seven tests that were green locally.

Both files now pin GJC_SESSION_ID in beforeAll and restore the previous
value in afterAll, matching the pattern already used by runs, report,
capabilities and the runtime suite. Verified by running with the variable
explicitly unset, which reproduces the CI failure before the fix and passes
after.

Lore-id: c9b8d2a7
Constraint: tests must not read ambient session state; pin it or pass it
Confidence: high
Scope-risk: narrow
Reversibility: easy
Directive: run `env -u GJC_SESSION_ID bun test ...` when a suite touches
  workflow state -- a green local run inside a GJC session proves nothing
  about a clean runner
Tested: env -u GJC_SESSION_ID over test/autoresearch/ is 85/85, and 273/273
  across the runtime suite, signal-teardown, default-gjc-definitions,
  cli-command-surface, gjc-skill-state-hooks, both computer suites, the
  descriptor registry, psmux-detect, workflow-hud-summary and the TUI
  autocomplete suite
…wnership

The mission `python` tool shipped with no operator doc, no model-facing
prompt file, and a kernel-ownership model that `docs/python-repl.md` still
described as session-keyed only. Three concrete gaps, all closed here.

`src/prompts/tools/python.md` is new, and the tool now imports it with
`{ type: "text" }` instead of carrying an inline description string. Every
other builtin already keeps its model-facing prompt in that directory, and
AGENTS.md forbids building prompts inline -- this tool was the exception.

`docs/tools/python.md` is new and matches the sibling per-tool docs: the
discoverable/defaultInactive registration and why activation must pass the
full merged tool list, the `execute`/`clear` actions with no separate
teardown tool, per-call mission resolution, and the fail-closed contract
that a missing or corrupt mission never degrades to an ad-hoc kernel.

`docs/python-repl.md` gains a Kernel ownership section distinguishing
session-owned kernels (`eval`) from explicitly-owned ones
(`autoresearch:<mission-id>`), and records that signal exit drains both
tool-cleanup registries -- the transition registry is where the SDK
actually puts a tool's `registerSessionCleanup`, and omitting it orphaned
the subprocess on Ctrl-C while graceful dispose looked fine.

`docs/tools/eval.md` gains a pointer so the two Python-running tools are
not confused.

Lore-id: c9c4e1b6
Constraint: documentation must match implemented behavior exactly -- every
  claim here was read back out of the shipped code, not the plan
Confidence: high
Scope-risk: narrow
Reversibility: easy
Tested: 209 tests green across the autoresearch suites, the mission
  runtime, signal-teardown, default-gjc-definitions, cli-command-surface,
  the descriptor registry and both computer suites; check:types and
  check:tools both pass, with the remaining biome warnings all in
  dev-only files. Verified the description now resolves from the .md and
  that the regenerated tool catalog and docs index both carry it
Expose the durable mission lifecycle through the CLI and align research-only guidance with its enforced contract.\n\nLore-id: pr4430-terminal\nConstraint: autoresearch never modifies product code\nConfidence: high\nScope-risk: wide\nReversibility: easy\nTested: coding-agent check:types and focused autoresearch/default-definition/CLI/skill-state/catalog suites
Scope mission kernels and artifacts by GJC session, persist public run/verdict state, and remove stale controller/catalog drift.\n\nLore-id: pr4430-terminal\nConstraint: autoresearch remains research-only\nConfidence: high\nScope-risk: wide\nReversibility: easy\nTested: coding-agent check/build; 279 focused autoresearch, CLI, definitions, controller-docs, pipeline, and computer safety tests
…ug alone

TerminalReviewA66 blocker 1. The live discoverable mission Python tool
derived its kernel owner as `autoresearch:<slug>`, while the public `clear`
verb disposed `autoresearch:<sessionId>:<slug>`. Two consequences, both
user-visible: `gjc autoresearch clear` never reached the running kernel and
left it resident, and two concurrent sessions on the same mission slug
shared one live kernel and therefore one Python namespace.

The mission-bound path had smuggled the session scope into the mission id
as `${sessionId}:${slug}`, so it happened to match `clear` while the
discoverable builtin did not. Both paths now go through one derivation,
`autoresearchKernelOwnerId(sessionId, missionId)`, and the session id is a
first-class field on the mission context rather than string-concatenated
into an id.

`AutoresearchReadReceipt` now carries the resolved `sessionId` so callers
derive owner identity from what was actually read instead of re-resolving
and drifting again.

Lore-id: cb2e8f41
Constraint: exactly one owner-id derivation; an inline template in either
  path is what caused this
Rejected: make `clear` use the slug-only owner | would reintroduce
  cross-session kernel sharing
Confidence: high
Scope-risk: moderate
Reversibility: easy
Tested: autoresearch suites 89/89 plus the mission runtime suite. Two new
  regression tests -- one asserting the live tool and `clear` derive the
  same owner, one asserting two sessions on the same slug get different
  owners -- proven fail-today by reintroducing the slug-only derivation
  (4 fail, then pass once restored)
Installing defaults only ever wrote the CURRENT set, so a definition
dropped from the bundle stayed under the agent dir forever. `team` was the
first removal, so it was the first to expose the gap: after upgrading,
`~/.gjc/agent/skills/team/SKILL.md` was still on disk, filesystem skill
discovery still found it, and `/skill:team` still resolved -- pointing at a
workflow whose command and runtime no longer exist.

Retirement quarantines rather than deletes. The directory moves to
`<targetRoot>/retired/<name>.<timestamp>/`, so a user who customized the
skill keeps their content and nothing is destroyed to satisfy a rename. The
timestamp means repeated retirements never overwrite an earlier quarantine.
`--check` reports what would move without touching the filesystem, and
`setup defaults` prints where each retired skill went.

Also sweeps the three translated READMEs, which the original change missed:
each still advertised `team` in its four-skill table, an opt-in `gjc rlm`
mode, and `gjc_delegate_team`. Only the English README had been updated.

Lore-id: ca1f7b3d
Constraint: never delete a user's skill directory to complete a rename --
  quarantine and report instead
Rejected: delete the retired directory outright | destroys a customized
  local skill with no recovery
Rejected: delete only when content matches the old bundled copy | we no
  longer ship that content, so there is nothing to compare against
Confidence: high
Scope-risk: narrow
Reversibility: easy
Directive: dropping a bundled default now requires adding it to
  RETIRED_GJC_DEFINITION_NAMES, or it lingers as a discoverable ghost skill
Tested: default-gjc-definitions 33/33 including four new cases --
  quarantine leaves the four current skills intact, --check stays
  read-only, absent retirees create no retired/ dir, and a second
  quarantine does not collide with the first. All four proven fail-today by
  disabling the retirement call. Verified end to end against a real
  installed layout: team disappears from skills/, the four current skills
  install, and the stale content survives under retired/. Types clean and
  the translated-README acceptance greps return nothing
Lore-id: cb3a9d52
Confidence: high
Scope-risk: narrow
TerminalReviewA66 blocker 2. `clear` removed only `mission.json` and left
`ledger.jsonl`, `runs.jsonl`, `experiment.json` and `runs/` in place, so a
successor mission in the same session inherited the previous mission's
events. `extractVerdictFromLedger` would surface a prior `verdict_issued`
as if it belonged to the new mission, and run history plus the metric
contract leaked the same way.

Clear now quarantines the entire working set to
`<dir>/retired/<slug>.<timestamp>/` rather than deleting it, so a completed
mission stays auditable while the successor starts from genuinely empty
state. The `kernel_cleared` row is appended to the OUTGOING ledger before
it moves, so the retired copy is a complete record ending with its own
clear instead of the clear vanishing from the audit trail.

Writing the tests found a real defect in my own earlier retirement work:
a timestamp-only directory name collides when two retirements land in the
same millisecond, silently overwriting the earlier quarantine. Both this
path and the bundled-definition retirement now reserve the directory with
an exclusive mkdir and disambiguate with a counter.

Lore-id: cb5d1e83
Constraint: never delete mission evidence to satisfy a restart -- quarantine
  and report where it went
Rejected: keep the ledger and filter by mission slug on read | leaves prior
  verdicts one bug away from resurfacing and grows unbounded
Confidence: high
Scope-risk: moderate
Reversibility: easy
Tested: 149 tests green across the mission runtime, the autoresearch suites
  and default-gjc-definitions, stable over three consecutive runs (the
  collision defect was intermittent, so repeat runs are the evidence).
  New cases cover: successor ledger empty after clear; retired ledger ends
  with its own kernel_cleared; a successor cannot see the prior verdict;
  clear with no mission is a no-op that creates no retired dir; two clears
  retire to distinct directories
…blic lifecycle

TerminalReviewA66 blocker 3. `createAutoresearchExperimentConfig` already
accepted `primaryMetric`, `metricUnit` and `direction`, but `AutoresearchMission`
had no metric fields, so nothing the public intake collected could reach it.
`autoresearchRunsStore` hardcoded `primaryMetric: "metric"` and inherited
lower-is-better, meaning a mission whose research contract is
higher-is-better silently optimized backwards and reported the wrong best run.

The mission artifact now carries an optional metric contract, both intakes
accept it (cold `write` fields, and `autoresearch-metric` /
`autoresearch-metric-unit` / `autoresearch-metric-direction` spec
declarations mirroring the existing `autoresearch-mode:` style), and the
values are threaded into the experiment config. Direction is validated at
the write boundary exactly like mode: an unrecognized value is rejected, not
coerced, so a typo cannot quietly restore the default. Read normalization
preserves the contract so it survives round-trips.

The fields stay OPTIONAL: a mission that declares nothing behaves exactly as
before.

Lore-id: cb7c4a96
Constraint: metric direction is never inferred or coerced -- same boundary
  discipline as mode
Rejected: default to higher-is-better when a unit looks like a rate | that
  is inference, which is what the mode rule exists to forbid
Confidence: high
Scope-risk: moderate
Reversibility: easy
Tested: 154 tests green across the mission runtime, autoresearch suites and
  default-gjc-definitions; types and check:tools clean. New cases cover a
  declared contract reaching the experiment config, the untouched default
  path, boundary rejection of an invalid direction on both intakes, and spec
  parsing. Proven fail-today by restoring the hardcoded metric name
…lation

TerminalReviewA66 blocker 4. The SKILL.md and AGENTS.md both state that
autoresearch produces findings and a verdict and never product code, but
nothing enforced it: `isPlanningSkill` deliberately excluded autoresearch,
so a mission could freely edit the user's working branch. A test even
asserted that contradiction as intended behavior.

A blanket block is not the answer -- `bash` is a gated tool, so it would
break the `autoresearch.sh` harness that experiments legitimately need.
Branch isolation is the authorization instead: on an `autoresearch/*`
branch every edit is contained and revertible through the existing
keep/discard machinery, so mutation is allowed; off that branch the mission
would be editing the user's working branch and is blocked with an actionable
message. Terminal mission phases release normally.

The branch is read live from the worktree via the existing
`getCurrentAutoresearchBranch`, not from recorded mission intent, because a
user can switch branches mid-mission and recorded intent would authorize
mutation that is no longer isolated.

Lore-id: cb9f2d74
Constraint: enforcement must not break the harness -- experiments are the
  workflow's actual work, so the exemption is branch-scoped rather than
  tool-scoped
Rejected: block outright in every phase | breaks autoresearch.sh and the
  data lane, making the workflow non-functional
Rejected: authorize from a recorded mission branch marker | records intent,
  not the current worktree, so switching branches silently defeats it
Confidence: medium
Scope-risk: moderate
Reversibility: easy
Directive: this is a security-relevant guard -- keep the branch check live;
  do not cache it into mission state
Tested: 215 tests green across the mutation guard, mission runtime, the
  autoresearch suites, default-gjc-definitions and skill-active-state;
  types, check:tools, check-visible-definitions, verify-gjc-skill-docs,
  verify-gjc-plugins, ci-gjc-state-gates and rebrand-inventory --strict all
  pass. Replaced the test that asserted the old exclusion with three real
  cases (blocked off-branch, allowed on an autoresearch branch, released at
  terminal phases); proven fail-today by re-excluding autoresearch
Not-tested: a live end-to-end harness run on a real autoresearch branch
Regenerated output differs from the committed copy by one newline in the
task-tool agents block. Generated files are generator-owned, so the
regenerated text wins.

Lore-id: cba1e7f0
Confidence: high
Scope-risk: narrow
… git

The blocker-4 unit coverage stubs `getCurrentAutoresearchBranch`, so it
proves the guard's branching logic but never that the real git read wires
up. Since the authorization is deliberately read live from the worktree
rather than from recorded mission intent, a stubbed test cannot catch a
regression in the read itself -- which is the whole mechanism.

This suite drives the full path with nothing mocked: real `git init`, a real
isolation branch created through the production `ensureAutoresearchBranch`,
real `git checkout`, and the real guard decision. It covers blocked on the
user's branch, allowed once isolated, re-blocked the moment the worktree
leaves the branch mid-mission, a lookalike `autoresearch-scratch` branch
that must NOT authorize, and terminal-phase release.

Writing it surfaced a real property of the production helper worth pinning:
mission state files are untracked, and an untracked-dirty worktree makes
`ensureAutoresearchBranch` take its degraded path and stay on the current
branch. The fixture therefore gitignores `.gjc/` exactly as a real GJC repo
does; without that the isolation branch is never created and the
authorization silently never applies.

Lore-id: cbc3f8e1
Constraint: no stubbing in this suite -- the point is the real git read
Confidence: high
Scope-risk: narrow
Reversibility: easy
Tested: 4/4 in the new suite; 157 tests green across the autoresearch
  suites, the mutation guard and the mission runtime, stable over two runs.
  Proven bidirectionally fail-today: re-excluding autoresearch from the
  guard fails 3 (enforcement gone), and removing the branch-isolation
  exemption fails 2 (legitimate experiment work wrongly blocked)
…rface

The extragoal and dogfood template tests still pinned the retired team
skill, failing CI shard 1 after the fourth canonical slot moved to
autoresearch.

Lore-id: 3f8a2b1e
Confidence: high
Scope-risk: narrow
Reversibility: trivial
Tested: both template tests pass against the bundled skills directory
@Yeachan-Heo
Yeachan-Heo force-pushed the feat/deprecate-team-skill-and-add-autoresearch-goal-skill branch from 95a40f6 to 1b183cc Compare August 17, 2026 10:03
@Yeachan-Heo
Yeachan-Heo marked this pull request as ready for review August 17, 2026 10:03
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant