Skip to content

fix: harden repo-local helper launcher resolution#90

Merged
PatrickSys merged 2 commits intomainfrom
feat/repo-local-helper-launcher
Apr 24, 2026
Merged

fix: harden repo-local helper launcher resolution#90
PatrickSys merged 2 commits intomainfrom
feat/repo-local-helper-launcher

Conversation

@PatrickSys
Copy link
Copy Markdown
Owner

Summary

  • add a generated repo-local .agents/bin/gsdd.mjs launcher as part of the portable runtime surface
  • route workflow helper commands through that launcher instead of bare gsdd ...
  • make launcher resolution deterministic: self-host the current framework repo when present, prefer the generating source checkout for local framework development, otherwise fall back to pinned gsdd-cli@<version>
  • treat the launcher as part of runtime-surface freshness and repair it through gsdd update
  • document that workflow helper commands using the launcher must run from the repo root

Root cause

Generated workflows assumed helper commands could call bare gsdd ..., but gsdd init only guaranteed generated files inside the repo, not an ambient PATH install. The first launcher draft still left two gaps: partial .agents/ installs were not fully self-repaired by gsdd update, and ambient PATH resolution could drift to the wrong CLI version.

Testing

  • node tests/gsdd.init.test.cjs
  • node tests/gsdd.manifest.test.cjs
  • node tests/phase.test.cjs
  • node tests/gsdd.scenarios.test.cjs
  • node tests/gsdd.health.test.cjs
  • node tests/gsdd.cross-runtime.test.cjs
  • node --test-name-pattern="Phase 18 deterministic CLI guards|G45 - Runtime Surface Freshness Contract|G10 - CLI Module Boundary" tests/gsdd.guards.test.cjs
  • node tests/gsdd.invariants.test.cjs

Copy link
Copy Markdown

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

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: ce4c11c1c7

ℹ️ 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 thread bin/lib/rendering.mjs Outdated
if (result.error.code === 'ENOENT') return false;
throw result.error;
}
process.exit(result.status ?? 0);
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 Propagate child termination signals in helper launcher

spawnSync returns status: null and sets signal when the child is terminated, but process.exit(result.status ?? 0) converts that into exit code 0. As a result, node .agents/bin/gsdd.mjs ... can report success even when the underlying gsdd command was killed (for example by SIGTERM/OOM/timeout), which allows workflows to continue after failed file-op/phase-status mutations. Treat signaled exits as failures (or re-emit the signal) instead of coercing them to success.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in the merged version. The generated workflow helper no longer proxies through a spawned child process; it dispatches the local helper commands directly from .planning/bin/gsdd.mjs, so the signal-to-success coercion path no longer exists.

Comment thread bin/lib/init-flow.mjs Outdated
}

if (platforms.length > 0 || existsSync(join(ctx.cwd, '.agents', 'skills'))) {
if (platforms.length > 0 || existsSync(join(ctx.cwd, '.agents'))) {
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 Restrict portable-surface update trigger to GSDD markers

This condition now treats any existing .agents/ directory as evidence that GSDD portable surfaces are installed. In repos that use .agents/ for unrelated tooling, gsdd update will unexpectedly generate .agents/skills/gsdd-* and .agents/bin/gsdd.mjs even when gsdd init was never run, causing unintended repository mutations. The trigger should check for explicit GSDD-owned paths (for example .agents/bin/gsdd.mjs or gsdd-* skill folders) rather than the top-level .agents directory.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed on main in 1b89a6a. gsdd update no longer treats .agents/ or a generic .agents/skills/ directory as GSDD-owned; the portable-surface trigger now requires an existing .agents/skills/gsdd-*/SKILL.md path, while initialized projects still repair from .planning/. Added regression coverage for an unrelated .agents/skills/custom-agent/SKILL.md directory to ensure no GSDD skills or planning state are generated.

@PatrickSys PatrickSys merged commit 5b33031 into main Apr 24, 2026
1 check passed
@PatrickSys PatrickSys deleted the feat/repo-local-helper-launcher branch April 24, 2026 15:50
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