Skip to content

Defense-in-depth: tighten BOOTSTRAP_AGENTS check to compare full subagent_type (not last segment) #4

@fernandoxavier02

Description

@fernandoxavier02

Priority: low — non-urgent. No exploit path today. Defense-in-depth hardening for a future-proofing scenario. Surfaced by adversarial review of the v4.1.0 release.

Context

v4.1.0 added pipeline-controller to the BOOTSTRAP_AGENTS whitelist in .claude/hooks/sentinel-hook.cjs to fix the cold-start bug (PR #3). The fix works correctly. This issue is about a latent improvement in the same area.

What the check does today

.claude/hooks/sentinel-hook.cjs:113-131:

const agentName = agentType.split(':').pop();
// ...
const BOOTSTRAP_AGENTS = ['task-orchestrator', 'pipeline-controller'];
if (BOOTSTRAP_AGENTS.includes(agentName)) {
  return process.exit(0); // fail-open: bootstrap permitted
}

The whitelist is compared against the last segment of subagent_type, not the full path.

The latent risk

A hypothetical subagent_type like someplugin:something:pipeline-controller would also pass the whitelist check. Currently this is impossible because line 109 filters startsWith('pipeline-orchestrator:') first — only agents owned by this plugin reach the whitelist comparison. So the latent vector is fully closed today.

The risk only materializes if another plugin in the future adopts the pipeline-orchestrator: prefix (intentionally or by accident), which would expand the whitelist implicitly.

Proposed fix (~2 lines)

Compare the full fully-qualified subagent_type instead of the last segment:

const FQ_BOOTSTRAP = [
  'pipeline-orchestrator:core:task-orchestrator',
  'pipeline-orchestrator:core:pipeline-controller'
];
if (FQ_BOOTSTRAP.includes(agentType)) {
  return process.exit(0);
}

Behavior is identical today. The change closes the latent vector at zero behavioral cost.

Acceptance criteria

  • sentinel-hook.cjs compares full subagent_type against an FQN whitelist
  • Existing test [6] (task-orchestrator bootstrap) still passes
  • Existing test [6b] (pipeline-controller bootstrap) still passes
  • New test added for the latent vector: someplugin:nested:pipeline-controller is denied (not bootstrapped)

Where to ship

Suggested release: v4.1.1 patch — bundled with any next behavioral change, no rush.

Discovery

Adversarial review of v4.1.0 release artifacts (Real-1 finding).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions