refactor: project-scoped context loading in session-start-context.sh #144
No reviewers
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
ldraney/claude-custom!144
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "143-refactor-session-start-context-sh-projec"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Replaces the project detection mechanism with a single
/repos/{name}endpoint lookup and scopes all downstream context (plan TOCs, semantic search, board items, project context) to the detected project. Falls back to current cross-project behavior when no project is detected. Maintains fail-open pattern throughout.Changes
hooks/session-start-context.sh:GET /repos/{repo-name}call. Extracts repo name viabasename. Moved detection early (after platform detection) sodetected_project_slugis available for all scoping.detected_project_slugfirst -- matching project gets full TOC, non-matching projects get one-liner. Falls back to board activity filter when no project detected.&project=${detected_project_slug}appended when a project is detected.Test Plan
bash -n hooks/session-start-context.shpassesclaude-customrepo as cwd: correctly detectspal-e-agencyvia/repos/claude-custom, shows structured TOC context, scoped board items with detailed titles, scoped plan TOCs/tmp(non-git directory): correctly falls back to unscoped cross-project behavior/repos/nonexistent-reporeturns 404,detected_project_slugstays empty, full cross-project loading occursReview Checklist
bash -nsyntax check passes|| trueon all fallible commands)set -eo pipefailpreserved{"slug": "...", "project": {"slug": "...", "name": "..."}}Related
Replace the project detection mechanism with a single /repos/{name} endpoint lookup instead of iterating all projects with URL normalization. Scope plan TOCs, semantic search, and board items to the detected project when available, falling back to current cross-project behavior when no project is detected. Changes (issue #143): - 20a: Project detection via /repos/{repo-name} endpoint - 20b: Plan TOC injection scoped to matching project - 20c: Semantic search scoped with &project= parameter - 20d: Board items detailed for matching board, summary for others - 20e: Structured project context (TOC sections + user stories pointer) replacing raw HTML dump Closes #143 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>Self-Review
Reviewed the diff against all five sub-tasks in issue #143. No blocking issues found.
20a (Project Detection): Clean single-endpoint lookup via
/repos/{repo-name}. Usesbasenameto extract repo name from git remote URL,curl -sfwith|| truefor fail-open. Moved early in the function sodetected_project_slugis available for all downstream scoping.20b (Plan TOC Scoping): When
detected_project_slugis set, only the matching project's plan gets full TOC injection. Non-matching plans get one-liner. When empty, falls back to original board activity filter. Correct priority ordering.20c (Semantic Search Scoping): Conditionally appends
&project=${detected_project_slug}to semantic search URL. Clean.20d (Board Item Scoping): Matching board shows item titles grouped by column (in_progress, qa, needs_approval). Other boards show summary counts. No-project path preserves existing aggregated behavior.
20e (Structured Project Context): Fetches project page TOC, checks for
user-storiesanchor, lists all sections, providesget_section()pointers. Eliminates the raw HTML dump (40 lines of stripped HTML). Multiple fallback paths if TOC fetch fails.Fail-open: All curl calls guarded with
|| true, all jq calls have validity checks.set -eo pipefailpreserved. Finalmain 2>/dev/null || exit 0untouched.Untouched sections confirmed: Personality injection, SOP loading, core SOPs, template reference, bug tracking instructions -- no changes.
Smoke tested: Both project-detected (claude-custom -> pal-e-agency) and no-project-detected (/tmp) paths produce correct output.
PR #144 Review
DOMAIN REVIEW
Tech stack: Bash shell script (Claude Code SessionStart hook). Domain checks: shell safety patterns, fail-open behavior,
jqusage,curlerror handling, variable scoping.20a -- Project detection via
/repos/{name}: Clean replacement. Thebasenameapproach correctly handles both HTTPS and SSH git URLs. The three-step validation (non-empty remote, non-empty repo_name, valid JSON with.project.slug) is sound. All steps have|| trueor2>/dev/nullguards.20b -- Plan TOC scoping: The priority logic is clear: detected project wins, then board activity, then no TOC. However, the old fail-open clause for plans with no
plan_project_slughas been dropped (see NITS below).20c -- Semantic search scoping: Simple
&project=parameter append. Clean.20d -- Board items scoping: The matched-board detailed view (showing
in_progress,qa,needs_approvalitem titles) is a significant improvement over raw counts. Theother_board_linessummary is well-structured. Theelsebranch preserves old aggregated behavior exactly.20e -- Structured project context: TOC-based approach is a clear win over the old raw HTML dump +
sedstrip. Theuser-storiesanchor detection is a nice touch. Falls back gracefully when TOC fetch fails.General observations:
set -eo pipefailis preserved (not shown in diff, but present in file header)|| truepattern maintained on all fallible commands in new codecwd_remotevariable declaration correctly moved from old position (line 373) to new position (line ~68); old declaration and entire old project detection block are fully removed -- no shadowingmatched_boardconventionboard-${detected_project_slug}correctly matchesboards-config.shnaming conventionBLOCKERS
None.
This is an infrastructure shell hook, not application code with a test harness. The
bash -nsyntax check and manual smoke testing (project-detected, no-project, fail-open with nonexistent repo) documented in the PR body are the appropriate validation level for this type of change. No BLOCKER criteria are triggered.NITS
Dropped fail-open for orphan plans (20b): The old code had a final
elif [[ -z "$plan_project_slug" ]]; then inject_toc=trueclause that ensured plans without a project slug would always get TOC injection (fail-open -- "can't match to board, fail open for this plan"). This clause is missing from BOTH the project-scoped path AND the unscopedeliffallback path in the new code. If any active plan lacks aproject.slug, it will silently lose its TOC injection. Consider restoring this fail-open clause in the unscoped path at minimum:Triple
jqparse ofrepo_response(20a): The response is piped throughjqthree times (validation, slug extraction, name extraction). Could be a singlejqcall extracting both values, e.g.:Not a correctness issue -- just unnecessary subprocess spawns on every session start.
Inconsistent "active" column definitions: The project-scoped board path (20d) counts
in_progress + qa + needs_approvalas "active" items. The unscoped path only countsin_progressandtodo. This is likely intentional (scoped = more detail) but the asymmetry could confuse consumers of the output.originremote assumption: Both old and new code usegit remote get-url origin. Per CLAUDE.md,pal-e-platformusesforgejoas its remote name, notorigin. This is NOT a regression (same behavior as before), but worth tracking as a known limitation.SOP COMPLIANCE
143-refactor-session-start-context-sh-projec(truncated but starts with143)plan-pal-e-agencyby slugbash -nsyntax validation documented as passingPROCESS OBSERVATIONS
/repos/{name}lookup adds 1 API call but the old project detection fetched/projects(all projects) + iterated + fetched individual project pages. Net reduction in API calls for the common case.VERDICT: APPROVED