os-sdlc hook: normalize namespaced subagent_type at hook ingestion #412

Closed
opened 2026-08-16 11:53:59 +00:00 by jared · 2 comments
Owner

Context

Child of #400. The PostToolUse hook reads subagent_type unmodified (plugins/os-sdlc/hooks/post_tool_use.rb:24-26) and compares it against bare agent names from maps/default.yaml at two downstream sites: TransitionTable#known_agent? (lib/os_sdlc/runner/transition_table.rb:62-64) and TicketFlow#matching_pending_dispatch (lib/os_sdlc/runner/ticket_flow.rb:10-17). Namespaced dispatch names like os-sdlc:programmer therefore never match, so the hook no-ops and stages must be advanced by manually piping bare-name events. Evidence brief: .sdlc/tickets/400/evidence-brief.md.

Tasks

  • Normalize the agent name once at the hook ingestion boundary (post_tool_use.rb), stripping a plugin namespace prefix, so downstream matching stays on bare names.
  • Tests in tests/runner/post_tool_use_hook_test.rb and tests/runner/post_tool_use_non_pipeline_async_dispatch_test.rb cover namespaced and bare dispatch names, including the ADR-0121 non-pipeline async no-op path.

Acceptance criteria

  • A dispatch with subagent_type os-sdlc:<stage> advances the pipeline identically to bare <stage>.
  • Non-pipeline namespaced agents (e.g. other plugins' agents) still no-op silently.
  • Suite green; changed files rubocop-clean.

Out of scope: GateEvaluator target_name env threading (#410); shakedown (#400).

## Context Child of #400. The PostToolUse hook reads `subagent_type` unmodified (plugins/os-sdlc/hooks/post_tool_use.rb:24-26) and compares it against bare agent names from maps/default.yaml at two downstream sites: TransitionTable#known_agent? (lib/os_sdlc/runner/transition_table.rb:62-64) and TicketFlow#matching_pending_dispatch (lib/os_sdlc/runner/ticket_flow.rb:10-17). Namespaced dispatch names like `os-sdlc:programmer` therefore never match, so the hook no-ops and stages must be advanced by manually piping bare-name events. Evidence brief: .sdlc/tickets/400/evidence-brief.md. ## Tasks - [ ] Normalize the agent name once at the hook ingestion boundary (post_tool_use.rb), stripping a plugin namespace prefix, so downstream matching stays on bare names. - [ ] Tests in tests/runner/post_tool_use_hook_test.rb and tests/runner/post_tool_use_non_pipeline_async_dispatch_test.rb cover namespaced and bare dispatch names, including the ADR-0121 non-pipeline async no-op path. ## Acceptance criteria - [ ] A dispatch with subagent_type `os-sdlc:<stage>` advances the pipeline identically to bare `<stage>`. - [ ] Non-pipeline namespaced agents (e.g. other plugins' agents) still no-op silently. - [ ] Suite green; changed files rubocop-clean. Out of scope: GateEvaluator target_name env threading (#410); shakedown (#400).
Author
Owner

Work starting on branch worktree-issue-412 (os-sdlc implement pipeline).

Work starting on branch worktree-issue-412 (os-sdlc implement pipeline).
Author
Owner

Resolution

Done: Hook now normalizes subagent_type at the ingestion boundary: normalize_agent strips the literal os-sdlc: prefix in plugins/os-sdlc/hooks/post_tool_use.rb, so namespaced pipeline dispatches advance identically to bare names while foreign-plugin namespaced agents still no-op silently (incl. the ADR-0121 async guard path). Test fixtures corrected to shipped bare-name maps; discriminating AC2 tests added.

Evidence: os-sdlc pipeline run to done on branch worktree-issue-412 (report .sdlc/tickets/412/briefs/013-review-to-done.md); reviewer APPROVE with mutation-check (strip-any fails, shipped fix passes); suite 950 runs 0 failures; changed files rubocop-clean; lint skip covered only 22 pre-existing offenses in untouched files, user-approved.

Follow-ups: Captured with skeptic verdicts: #413 (resolve_slug drops target, multi-target intake broken), #414 (tea 0.13.0 broke --output yaml BodyFetch), #415 (worktrees miss .cc-os/config), #416 (lint gate scopes whole target, not changed files), #417 (agent charter drift enforcement). No others.

## Resolution **Done:** Hook now normalizes subagent_type at the ingestion boundary: normalize_agent strips the literal os-sdlc: prefix in plugins/os-sdlc/hooks/post_tool_use.rb, so namespaced pipeline dispatches advance identically to bare names while foreign-plugin namespaced agents still no-op silently (incl. the ADR-0121 async guard path). Test fixtures corrected to shipped bare-name maps; discriminating AC2 tests added. **Evidence:** os-sdlc pipeline run to done on branch worktree-issue-412 (report .sdlc/tickets/412/briefs/013-review-to-done.md); reviewer APPROVE with mutation-check (strip-any fails, shipped fix passes); suite 950 runs 0 failures; changed files rubocop-clean; lint skip covered only 22 pre-existing offenses in untouched files, user-approved. **Follow-ups:** Captured with skeptic verdicts: #413 (resolve_slug drops target, multi-target intake broken), #414 (tea 0.13.0 broke --output yaml BodyFetch), #415 (worktrees miss .cc-os/config), #416 (lint gate scopes whole target, not changed files), #417 (agent charter drift enforcement). No others.
jared closed this issue 2026-08-16 12:37:26 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jared/cc-os#412
No description provided.