Skip to content

fix: harden runtime boundaries and resource lifecycles - #1

Merged
lidge-jun merged 1 commit into
lidge-jun:devfrom
Ingwannu:agent/harden-runtime-boundaries
Aug 9, 2026
Merged

fix: harden runtime boundaries and resource lifecycles#1
lidge-jun merged 1 commit into
lidge-jun:devfrom
Ingwannu:agent/harden-runtime-boundaries

Conversation

@Ingwannu

Copy link
Copy Markdown

What

  • Unifies the Vite and production loopback API boundary with bounded JSON parsing.
  • Hardens goalplan, recall, subagent configuration, recursion grants, evidence gates, and hook input handling.
  • Bounds runner JSONL/output, event-log backpressure, media streaming/concurrency, job retention, maps, timers, and process-group shutdown.
  • Improves GUI polling and route splitting, static asset caching, Discord/Telegram isolation, and dependency security.
  • Documents the runtime trust boundaries and decision rationale.

Why / root cause

Several independently grown runtime paths had inconsistent trust rules and unbounded resource lifecycles. Oversized or child-controlled input could bypass policy checks, while slow storage, concurrent downloads, stale jobs, event streams, and descendant processes could retain resources indefinitely.

Compatibility and impact

Normal-size API requests, messages, attachments, subagent dispatch, and recent job history keep their existing behavior. Intentional limits affect only overload or unsafe cases:

  • enforcement hook stdin and Codex events are bounded and fail closed or report truncation;
  • recursive delegation uses a parent-minted one-use capability;
  • Git-tracked subagent overrides require a repository-and-digest-bound review token;
  • media overload is rejected with a retry message;
  • stale running jobs are reconciled after restart;
  • old job rows are pruned by count and age.

Verification

  • npm test: 1,453 passed, 0 failed
  • npm run build: 119 files compiled and layout validated
  • GUI production build: Vite 6.4.3, main chunk 159.04 kB / 52.29 kB gzip
  • GUI TypeScript check: passed
  • npm audit --audit-level=low: 0 vulnerabilities
  • npm run gate: passed
  • git diff --check: passed
  • Independent final diff review: no blocker or high-severity regression found

@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown

Target branch corrected

This pull request now targets dev.

The [WRONG BRANCH] title prefix has been removed. Its existing draft status has been preserved.

@github-actions github-actions Bot changed the title fix: harden runtime boundaries and resource lifecycles [WRONG BRANCH] fix: harden runtime boundaries and resource lifecycles Jul 27, 2026
@Ingwannu
Ingwannu changed the base branch from main to dev July 27, 2026 07:22
@github-actions github-actions Bot changed the title [WRONG BRANCH] fix: harden runtime boundaries and resource lifecycles fix: harden runtime boundaries and resource lifecycles Jul 27, 2026
@lidge-jun
lidge-jun marked this pull request as ready for review August 9, 2026 01:18
@lidge-jun
lidge-jun merged commit dac77cc into lidge-jun:dev Aug 9, 2026
2 checks passed

@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: 8f2efabfe3

ℹ️ 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 +781 to +783
const recursionRequested = !spawnedBySubagent && message.includes(SUBSPAWN_TOKEN);
const mintedGrant = recursionRequested ? mintRecursionGrant(obj) : null;
const controlledMessage = stripControlMarkers(message);

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 Preserve recursion grants across repeated hook passes

When a host applies the hook twice to a root coordinator spawn, the first pass has already removed SUBSPAWN_TOKEN, so the second pass sets recursionRequested to false and stripControlMarkers deletes the minted CXC-SUBSPAWN-GRANT. It then prepends a leaf guard, leaving the coordinator unable to perform its authorized child spawn despite the idempotence guarantee below. Re-running runSpawnAttachHook on its own first-pass updatedInput.message reproduces the lost grant.

Useful? React with 👍 / 👎.

Comment on lines 263 to +270
export function terminateChild(child: ChildProcess): void {
if (child.exitCode !== null || child.signalCode !== null) return;
child.kill("SIGTERM");
// `exit` does not imply the process group is gone: a grandchild can retain an
// inherited stdout/stderr descriptor and prevent Node's `close` event. Always
// signal the detached group while the runner still owns this ChildProcess.
signalProcessTree(child, "SIGTERM");
if (process.platform !== "win32") {
const timer = setTimeout(() => {
if (child.exitCode === null && child.signalCode === null) child.kill("SIGKILL");
signalProcessTree(child, "SIGKILL");

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 Ensure SIGTERM removes detached descendants promptly

When the direct Codex process exits after spawning a descendant that inherits its output pipe, this group-level SIGTERM does not remove the descendant before runTurn returns; the newly added runTurn: timeout kills a process group after the direct child has exited test consistently finds the PID still reachable, and the test process remains open until the three-second SIGKILL fallback. Timed-out turns can therefore leave helper processes and inherited resources alive during the grace period rather than satisfying the intended process-tree cleanup.

Useful? React with 👍 / 👎.

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.

2 participants