Skip to content

GIT-869c63k1e: enforce ClickUp branch/PR/commit linking guardrails#89

Merged
TonyCasey merged 10 commits into
mainfrom
codex/GIT-869c63k1e_clickup-linking-guardrails
Feb 17, 2026
Merged

GIT-869c63k1e: enforce ClickUp branch/PR/commit linking guardrails#89
TonyCasey merged 10 commits into
mainfrom
codex/GIT-869c63k1e_clickup-linking-guardrails

Conversation

@TonyCasey
Copy link
Copy Markdown
Owner

@TonyCasey TonyCasey commented Feb 17, 2026

Summary

  • add PR workflow checks for ClickUp task ID in branch + PR metadata
  • enforce ClickUp task ID in commit messages via git-mem commit-msg hook
  • add PR template with ClickUp task fields
  • update workflow docs naming example

ClickUp Task

Task ID: GIT-869c63k1e
Task Link: https://app.clickup.com/t/869c63k1e
Raw Task ID: 869c63k1e

Validation

  • npm run type-check
  • node --import tsx --test tests/unit/hooks/commit-msg.test.ts

Summary by CodeRabbit

  • New Features

    • Session runtime tracking persisted across sessions with automatic activation/deactivation and environment-based agent/model detection.
    • Runtime persistence service to store short-lived session metadata.
  • Documentation

    • Updated branch naming guidance to use ClickUp task IDs.
    • Added a PR template with validation checklists.
  • Process Improvements

    • Enforced ClickUp task linking and commit-message ClickUp ID validation (hook version bumped).
    • CI checks enforcing Sonar quality gates and review/reply/resolution rules.
  • Tests

    • Added comprehensive tests for runtime persistence and session lifecycle handling.

TonyCasey and others added 5 commits February 16, 2026 12:43
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
AI-Agent: Claude-Code/2.1.42
AI-Model: claude-opus-4-5-20251101
AI-Fact: add claude to test.txt. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
AI-Confidence: low
AI-Lifecycle: project
AI-Memory-Id: f5ea4bbd
AI-Source: heuristic
AI-Confidence: low
AI-Lifecycle: project
AI-Memory-Id: 1980faea
AI-Source: heuristic
When git-mem hooks run in plain terminal shells (e.g., post-commit),
no AI environment variables are set. This causes agent/model detection
to fail, meaning commits made during AI sessions don't get properly
attributed with AI-Agent and AI-Model trailers.

Solution:
- Write runtime.json to .git-mem/ on session-start with detected agent/model
- AgentResolver reads this file as fallback when env vars are empty
- Delete runtime.json on session-stop to prevent stale attribution
- TTL enforcement (2h default) prevents stale data from being used

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
AI-Agent: Claude-Code/2.1.42
AI-Model: claude-opus-4-5-20251101
AI-Decision: add runtime.json for cross-hook agent/model detection (GIT-123). When git-mem hooks run in plain terminal shells (e.g., post-commit),
AI-Confidence: medium
AI-Tags: application, handlers, domain, infrastructure, services, tests, unit
AI-Lifecycle: project
AI-Memory-Id: 42af7fc0
AI-Source: heuristic
- RuntimeService: reject NaN/invalid timestamps and future timestamps
  (with 1 minute skew allowance)
- SessionStopHandler: move deactivateRuntime to finally block so it
  runs even when capture fails
- SessionStartHandler: use env-only detection functions to avoid
  runtime.json loop when activating
- AgentResolver: cache runtime.json read to avoid repeated file I/O
- IRuntimeService: fix doc comment (errors silently ignored, not logged)
- Remove accidental test.txt file

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
AI-Agent: Claude-Code/2.1.42
AI-Model: claude-opus-4-5-20251101
AI-Convention: runtime.json loop when activating
AI-Confidence: medium
AI-Tags: application, handlers, domain, infrastructure, services, tests, unit, pattern:avoid
AI-Lifecycle: project
AI-Memory-Id: 70a43cb3
AI-Source: heuristic
ClickUp task: 869c63k1e

https: //app.clickup.com/t/869c63k1e
AI-Agent: Codex/0.92.0
AI-Model: gpt-5.3-codex
AI-Fact: enforce ClickUp linking guardrails GIT-869c63k1e. ClickUp task: 869c63k1e
AI-Confidence: low
AI-Tags: hooks, tests, unit
AI-Lifecycle: project
AI-Memory-Id: 00f9d6ef
AI-Source: heuristic
Copilot AI review requested due to automatic review settings February 17, 2026 15:21
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

Refactor repeated temp-dir setup/cleanup into withTestDir helper and use node:* imports.

AI-Agent: Codex/0.92.0
AI-Model: gpt-5.3-codex
AI-Decision: The withTestDir helper pattern provides automatic cleanup using try-finally to ensure temporary directories are always removed even if tests fail.
AI-Confidence: high
AI-Tags: testing, refactoring, test-helpers, node-js, imports, modules, resource-management, cleanup, temp-directories, runtime-service, filesystem
AI-Lifecycle: project
AI-Memory-Id: 87292011
AI-Source: llm-enrichment
@TonyCasey
Copy link
Copy Markdown
Owner Author

Addressed Sonar duplication feedback by refactoring runtime service tests to remove repeated setup/cleanup blocks and reducing duplicated new code. Also updated runtime service imports to node:* style in the same area.\n\nRelated task: GIT-869c63k1e

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 17, 2026

📝 Walkthrough

Walkthrough

Adds a runtime session persistence feature (IRuntimeService + RuntimeService) with activation on session start and deactivation on session stop, DI wiring for runtime support and agent/model detection fallback, ClickUp task validation in hooks/workflows, PR governance workflows, tests, and a PR template.

Changes

Cohort / File(s) Summary
GitHub config
\.github/pull_request_template.md, \.github/workflows/clickup-linking.yml, \.github/workflows/pr-governance.yml
Add PR template; add ClickUp linking workflow enforcing branch→task ID consistency and PR inclusion; add PR governance workflow enforcing Sonar quality gate and inline-review/replies checks.
Domain contract
src/domain/interfaces/IRuntimeService.ts
Add IRuntimeData and IRuntimeService interfaces (activate/deactivate/read) describing runtime.json shape, TTL semantics, and no-throw expectations.
Runtime implementation & tests
src/infrastructure/services/RuntimeService.ts, tests/unit/infrastructure/services/RuntimeService.test.ts
New RuntimeService implementing persistence to .git-mem/runtime.json with activate/deactivate/read (timestamp/TTL validation, 1-min skew, safe-fail); comprehensive unit tests for activation, deactivation, and read edge cases.
Agent resolution
src/infrastructure/services/AgentResolver.ts
AgentResolver now accepts optional runtimeService and cwd, lazily caches runtime data, prefers env detection then falls back to runtime.json for agent/model.
Session handlers & tests
src/application/handlers/SessionStartHandler.ts, src/application/handlers/SessionStopHandler.ts, tests/unit/application/handlers/SessionStartHandler.test.ts, tests/unit/application/handlers/SessionStopHandler.test.ts
SessionStartHandler accepts runtimeService and detectAgent/detectModel to activate runtime.json (safe, non-throwing); SessionStopHandler accepts runtimeService and always calls deactivate in a finally block; tests added/extended to cover activation/deactivation and error-tolerant behavior.
DI wiring & types
src/infrastructure/di/container.ts, src/infrastructure/di/types.ts
Register runtimeService in DI cradle, expose it on ICradle, convert agentResolver to factory wired with runtimeService/cwd, and pass runtimeService/detectors into session handlers.
Git hooks & tests
src/hooks/commit-msg.ts, tests/unit/hooks/commit-msg.test.ts
Bump commit-msg hook fingerprint v6→v7 and add pre-check requiring ClickUp/GIT- in commit messages; tests updated to expect new version and validation message.
Docs
CLAUDE.md
Update branch naming guidance to require ClickUp task-based branch names and add PR/Sonar review requirements.

Sequence Diagram

sequenceDiagram
    rect rgba(200,200,255,0.5)
    actor Dev
    participant SessionStart as SessionStartHandler
    participant Detect as detectAgent/detectModel
    participant Runtime as RuntimeService
    participant FS as .git-mem/runtime.json
    end

    Dev->>SessionStart: start(sessionId)
    SessionStart->>Detect: detectAgent(), detectModel()
    Detect-->>SessionStart: agent, model
    SessionStart->>Runtime: activate({sessionId, agent, model, timestamp, source})
    Runtime->>FS: write runtime.json
    FS-->>Runtime: write success
    Runtime-->>SessionStart: success (no-throw)
    SessionStart-->>Dev: started

    rect rgba(200,255,200,0.5)
    participant AgentResolver as AgentResolver
    Dev->>AgentResolver: resolveAgent()/resolveModel()
    AgentResolver->>Runtime: read(ttl)
    Runtime-->>AgentResolver: runtime data (if fresh)
    AgentResolver-->>Dev: agent/model (env or fallback)
    end

    rect rgba(255,200,200,0.5)
    actor Dev2
    participant SessionStop as SessionStopHandler
    Dev2->>SessionStop: stop(sessionId)
    SessionStop->>Runtime: deactivate()
    Runtime->>FS: delete runtime.json
    FS-->>Runtime: delete success
    Runtime-->>SessionStop: success (no-throw)
    SessionStop-->>Dev2: stopped
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title directly reflects the main objective: enforcing ClickUp branch/PR/commit linking guardrails via task ID validation across workflows, PR templates, and commit hooks.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/GIT-869c63k1e_clickup-linking-guardrails

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR enforces ClickUp task ID linking across GitHub branches, PRs, and commit messages to improve project tracking and integration between GitHub and ClickUp.

Changes:

  • Added GitHub workflow to validate ClickUp task IDs in branch names and PR metadata
  • Added commit-msg hook validation requiring ClickUp task IDs in all commits
  • Implemented RuntimeService for persisting AI agent/model detection across hook invocations

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
.github/workflows/clickup-linking.yml New workflow enforcing ClickUp task ID presence in branch names and PR title/body
.github/pull_request_template.md New PR template with ClickUp task ID fields
CLAUDE.md Updated workflow documentation from Linear to ClickUp task naming
src/hooks/commit-msg.ts Added validation requiring ClickUp task ID in commit messages (v7)
tests/unit/hooks/commit-msg.test.ts Updated tests for v7 hook fingerprint and new validation
src/domain/interfaces/IRuntimeService.ts New interface for runtime session data persistence
src/infrastructure/services/RuntimeService.ts New service implementing runtime.json read/write with TTL validation
src/infrastructure/services/AgentResolver.ts Enhanced with runtime.json fallback for agent/model detection
src/application/handlers/SessionStartHandler.ts Added runtime.json activation on session start
src/application/handlers/SessionStopHandler.ts Added runtime.json deactivation on session stop
src/infrastructure/di/container.ts Registered RuntimeService and updated AgentResolver dependencies
src/infrastructure/di/types.ts Added runtimeService to dependency injection types
tests/unit/infrastructure/services/RuntimeService.test.ts Comprehensive test coverage for RuntimeService
tests/unit/application/handlers/SessionStartHandler.test.ts Added tests for runtime activation behavior
tests/unit/application/handlers/SessionStopHandler.test.ts Added tests for runtime deactivation behavior

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/infrastructure/services/RuntimeService.ts Outdated
Comment thread src/application/handlers/SessionStopHandler.ts Outdated
Consolidate missing/invalid JSON read checks into one case to reduce Sonar duplication.

AI-Agent: Codex/0.92.0
AI-Model: gpt-5.3-codex
AI-Convention: Test consolidation is preferred over duplication to satisfy Sonar code quality rules, even when it means combining logically separate test scenarios.
AI-Confidence: verified
AI-Tags: testing, sonar, code-quality, test-consolidation, runtime-service, error-handling, json-parsing, file-operations, file-structure, git-mem, json-storage
AI-Lifecycle: project
AI-Memory-Id: 5642fc55
AI-Source: llm-enrichment
Use CLOCK_SKEW_ALLOWANCE_MS constant and remove uninitialized handlerResult path.

AI-Agent: Codex/0.92.0
AI-Model: gpt-5.3-codex
AI-Decision: Clock skew allowance for runtime data validation is set to 1 minute (60,000ms) to handle minor timestamp discrepancies between systems.
AI-Confidence: verified
AI-Tags: error-handling, variable-initialization, session-stop-handler, runtime-service, clock-skew, timestamp-validation, constants, magic-numbers, code-quality, cleanup, finally-block
AI-Lifecycle: project
AI-Memory-Id: d6a8f851
AI-Source: llm-enrichment
Copilot AI review requested due to automatic review settings February 17, 2026 15:33
@TonyCasey
Copy link
Copy Markdown
Owner Author

Addressed both open Copilot review threads in commit 3d90836:

  1. Thread PRRT_kwDORJMSCs5vFZQM (RuntimeService.ts)
  • Replaced magic number with CLOCK_SKEW_ALLOWANCE_MS and used it in the skew check.
  1. Thread PRRT_kwDORJMSCs5vFZQx (SessionStopHandler.ts)
  • Refactored handle to return directly from try/catch while preserving finally runtime deactivation, removing the uninitialized handlerResult state.

Validated with:

  • node --import tsx --test tests/unit/application/handlers/SessionStopHandler.test.ts
  • node --import tsx --test tests/unit/infrastructure/services/RuntimeService.test.ts
  • npm run type-check

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/infrastructure/services/RuntimeService.ts (1)

62-67: Incomplete runtime data validation may return malformed objects.

The type assertion as IRuntimeData at line 62 bypasses TypeScript's type safety. The validation only checks timestamp, but IRuntimeData requires sessionId, agent, model, and source fields. Callers may receive an object missing required fields.

Consider validating the complete structure:

♻️ Proposed validation enhancement
       const content = readFileSync(filePath, 'utf8');
-      const data = JSON.parse(content) as IRuntimeData;
+      const parsed = JSON.parse(content) as Record<string, unknown>;

       // Validate structure
-      if (!data || typeof data.timestamp !== 'string') {
+      if (
+        !parsed ||
+        typeof parsed.sessionId !== 'string' ||
+        typeof parsed.timestamp !== 'string' ||
+        typeof parsed.source !== 'string'
+      ) {
         return undefined;
       }
+
+      const data = parsed as IRuntimeData;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/infrastructure/services/RuntimeService.ts` around lines 62 - 67, The
current parsing in RuntimeService.ts casts JSON to IRuntimeData then only checks
timestamp, which can return malformed objects; update the parsing/validation
around the const data variable so you parse into an unknown, remove the unsafe
"as IRuntimeData" cast, and explicitly validate that sessionId, agent, model,
source and timestamp exist and are strings (or other required shapes) before
returning — if any are missing/invalid return undefined; reference the parsed
variable "data" and the IRuntimeData type to locate where to add these checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/infrastructure/services/RuntimeService.ts`:
- Around line 62-67: The current parsing in RuntimeService.ts casts JSON to
IRuntimeData then only checks timestamp, which can return malformed objects;
update the parsing/validation around the const data variable so you parse into
an unknown, remove the unsafe "as IRuntimeData" cast, and explicitly validate
that sessionId, agent, model, source and timestamp exist and are strings (or
other required shapes) before returning — if any are missing/invalid return
undefined; reference the parsed variable "data" and the IRuntimeData type to
locate where to add these checks.

Require Sonar pass + zero new issues and enforce inline-replied, resolved review threads.

AI-Agent: Codex/0.92.0
AI-Model: gpt-5.3-codex
AI-Fact: enforce sonar and inline review governance GIT-869c63k1e. Require Sonar pass + zero new issues and enforce inline-replied, resolved review threads.
AI-Confidence: low
AI-Tags: config, docs
AI-Lifecycle: project
AI-Memory-Id: c1d001da
AI-Source: heuristic
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/pr-governance.yml:
- Around line 63-99: The GraphQL query is paginated (reviewThreads(first:100)
and comments(first:100)) which can miss threads/comments; update the workflow to
detect and handle pagination by requesting pageInfo (endCursor, hasNextPage) for
reviewThreads and comments in the query and then either iterate using the
endCursor to fetch all pages (loop the gh api graphql call until hasNextPage is
false) or fail the check when pageInfo.hasNextPage is true so the run is
considered incomplete; adjust the variables and jq logic that compute pr_author,
unresolved_count and missing_inline_reply_count to aggregate across all pages
(or short-circuit with a failing message) rather than relying only on the first
100 items.
- Around line 16-51: The SonarCloud API calls use curl in the for-loop and when
building issues_response without authentication or the organization parameter;
update both curl invocations to use Basic auth via -u "${SONAR_TOKEN}:" and
append the organization query param using SONAR_ORGANIZATION (e.g. add
&organization=${SONAR_ORGANIZATION}) so the requests target the correct org, and
ensure SONAR_PROJECT_KEY usage (the variable referenced as SONAR_PROJECT_KEY)
remains the project key only while organization is passed separately; preserve
existing variables PR_NUMBER, quality_status and issues_response logic but
modify the curl invocations accordingly and ensure SONAR_TOKEN and
SONAR_ORGANIZATION are required env inputs.

Comment thread .github/workflows/pr-governance.yml
Comment thread .github/workflows/pr-governance.yml
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread CLAUDE.md Outdated
Comment thread .github/workflows/pr-governance.yml
Comment thread .github/workflows/pr-governance.yml Outdated
Comment thread .github/workflows/pr-governance.yml
Comment thread .github/workflows/pr-governance.yml
Add Sonar auth/org support, GH token for gh api, pagination safeguards, doc naming alignment, and Sonar issue fixes.

AI-Agent: Codex/0.92.0
AI-Model: gpt-5.3-codex
AI-Gotcha: address PR governance and review feedback GIT-869c63k1e. Add Sonar auth/org support, GH token for gh api, pagination safeguards, doc naming alignment, and Sonar issue fixes.
AI-Confidence: medium
AI-Tags: infrastructure, services, tests, unit
AI-Lifecycle: project
AI-Memory-Id: bf652dba
AI-Source: heuristic
@TonyCasey TonyCasey force-pushed the codex/GIT-869c63k1e_clickup-linking-guardrails branch from 2786409 to 8380710 Compare February 17, 2026 15:57
@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/pr-governance.yml:
- Around line 19-20: The workflow uses an invalid GitHub Actions expression
replace(...) for SONAR_PROJECT_KEY causing a syntax error; remove the replace
fallback and instead set SONAR_PROJECT_KEY to a safe default (e.g., use
github.repository directly) in the job/env and compute the sanitized value in
the shell step that runs (sanitize by replacing '/' with '_' in the script), or
use available expression helpers like format() if suitable; update the
SONAR_PROJECT_KEY reference and any steps that rely on it to use the computed
sanitized value (look for SONAR_PROJECT_KEY and the erroneous replace(...) usage
to locate the code).

In `@src/infrastructure/services/AgentResolver.ts`:
- Around line 54-60: In getRuntimeData(), replace the nullish coalescing
assignment on cachedRuntimeData with a plain assignment since runtimeDataLoaded
is false only when cachedRuntimeData is undefined; specifically set
this.cachedRuntimeData = this.runtimeService?.read(this.cwd) (still guarded by
runtimeService) and keep the runtimeDataLoaded flag behavior in the same method
to simplify the logic.

Comment thread .github/workflows/pr-governance.yml
Comment thread src/infrastructure/services/AgentResolver.ts
@TonyCasey TonyCasey merged commit 8f6cba4 into main Feb 17, 2026
6 checks passed
@TonyCasey TonyCasey deleted the codex/GIT-869c63k1e_clickup-linking-guardrails branch February 17, 2026 16:10
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