Skip to content

fix(continuous-learning-v2): accept claude-vscode as valid entrypoint - #2134

Merged
affaan-m merged 1 commit into
affaan-m:mainfrom
gaurav0107:fix/2102-observe-sh-silently-exits-on-vs-code-ext-v2
Jun 7, 2026
Merged

affaan-m merged 1 commit into
affaan-m:mainfrom
gaurav0107:fix/2102-observe-sh-silently-exits-on-vs-code-ext-v2

Conversation

@gaurav0107

@gaurav0107 gaurav0107 commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Summary

The continuous-learning-v2/observe.sh Layer 1 entrypoint guard short-circuits with exit 0 when CLAUDE_CODE_ENTRYPOINT is not in {cli, sdk-ts, claude-desktop}. Claude Code's VS Code extension sets CLAUDE_CODE_ENTRYPOINT=claude-vscode, so VS Code users see no observations recorded — observations.jsonl is never created and the downstream instinct/pattern pipeline stays empty.

This PR adds claude-vscode to the allowlist alongside the existing entries, mirroring the precedent in #1522 (which added claude-desktop for exactly the same reason). The change is a single-token addition on one line of skills/continuous-learning-v2/hooks/observe.sh.

A new regression test (tests/hooks/observe-entrypoint-allowlist.test.js) pins the allowlist by spawning observe.sh under bash -x for each entrypoint value and asserting that allowed entrypoints reach Layer 2's ECC_HOOK_PROFILE check while denied entrypoints stop at Layer 1.

Verification

  • node tests/hooks/observe-entrypoint-allowlist.test.js — 7/7 pass (4 allowed entrypoints reach Layer 2; 3 denied entrypoints stop at Layer 1).
  • node tests/run-all.js — full suite green locally.
  • node scripts/ci/validate-skills.js — pass.
  • npx eslint scripts/**/*.js tests/**/*.js — pass.
  • npx markdownlint-cli '**/*.md' --ignore node_modules — pass.
  • Negative-revert verified: reverting the one-token change causes claude-vscode reaches Layer 2 to fail, confirming the test pins the allowlist.

Fixes #2102


Summary by cubic

Allow claude-vscode as a valid CLAUDE_CODE_ENTRYPOINT so continuous-learning-v2/observe.sh no longer exits early for VS Code users. Fixes #2102 by ensuring observations are recorded and observations.jsonl is created.

  • Bug Fixes
    • Added claude-vscode to the Layer 1 entrypoint allowlist in skills/continuous-learning-v2/hooks/observe.sh.
    • Added a regression test (tests/hooks/observe-entrypoint-allowlist.test.js) to pin the allowlist and verify allowed entrypoints reach Layer 2 (ECC_HOOK_PROFILE).

Written for commit 08aacc8. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Added claude-vscode as a supported code entrypoint
  • Tests

    • Added regression test for entrypoint allowlist validation

The observe.sh Layer 1 entrypoint guard short-circuits with exit 0 when
CLAUDE_CODE_ENTRYPOINT is not in {cli, sdk-ts, claude-desktop}. Claude
Code's VS Code extension sets CLAUDE_CODE_ENTRYPOINT=claude-vscode, so
VS Code users see no observations recorded — observations.jsonl never
gets created and the instinct pipeline stays empty.

Add claude-vscode to the allowlist, mirroring the precedent in affaan-m#1522
which added claude-desktop the same way.

Add a regression test that spawns observe.sh under bash -x for each
allowed entrypoint (cli, sdk-ts, claude-desktop, claude-vscode) and
each denied entrypoint (unknown-host, claude-cody, mcp), asserting
that allowed entrypoints reach Layer 2's ECC_HOOK_PROFILE check while
denied entrypoints stop at Layer 1.

Fixes affaan-m#2102
@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds claude-vscode to the observe.sh Layer 1 entrypoint allowlist to enable VS Code extension observations, then validates the fix with a regression test that inspects bash trace behavior to confirm allowlisted entrypoints reach Layer 2 while denied ones remain at Layer 1.

Changes

Entrypoint Allowlist Fix and Validation

Layer / File(s) Summary
Entrypoint allowlist expansion
skills/continuous-learning-v2/hooks/observe.sh
The CLAUDE_CODE_ENTRYPOINT case pattern adds claude-vscode to the allowlist of recognized entrypoints.
Entrypoint allowlist regression test
tests/hooks/observe-entrypoint-allowlist.test.js
Comprehensive Node.js test that spawns observe.sh post under bash -x tracing with deterministic ECC_HOOK_PROFILE=minimal injection, extracts Layer 2 reachability from stderr markers, and validates that cli, sdk-ts, claude-desktop, and claude-vscode reach Layer 2 while other entrypoints do not.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A VS Code extension now plays,
With claude-vscode's allowlist praise!
Traces bloom bright beneath bash -x,
Regression tests lock in the fix. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding claude-vscode as a valid entrypoint in the continuous-learning-v2 observe.sh script.
Linked Issues check ✅ Passed The PR fully addresses issue #2102 by adding claude-vscode to the entrypoint allowlist in observe.sh and includes a regression test validating the fix works correctly.
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #2102: the observe.sh modification adds claude-vscode to the allowlist, and the new test validates entrypoint allowlist behavior without introducing unrelated code.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@gaurav0107
gaurav0107 marked this pull request as ready for review June 3, 2026 18:47
@gaurav0107
gaurav0107 requested a review from affaan-m as a code owner June 3, 2026 18:47

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
tests/hooks/observe-entrypoint-allowlist.test.js (3)

57-61: ⚡ Quick win

Avoid silently swallowing cleanup failures.

Line 57-61 has an empty catch block. At minimum, capture and surface cleanup errors in a controlled way (e.g., debug output) so failures are diagnosable.

As per coding guidelines, "Always handle errors explicitly at every level and never silently swallow errors".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/hooks/observe-entrypoint-allowlist.test.js` around lines 57 - 61, The
empty catch around fs.rmSync(dir, { recursive: true, force: true }) swallows
cleanup errors; update the catch to explicitly handle and surface failures
(e.g., log with console.error or the test logger) including the directory name
and error object so failures are diagnosable, or rethrow if appropriate for the
test; locate the try/catch that wraps fs.rmSync for variable dir in
tests/hooks/observe-entrypoint-allowlist.test.js and replace the silent ignore
with an explicit error handling statement that records the error details.

103-114: ⚡ Quick win

Make Layer 2 trace detection less brittle across Bash/xtrace formats.

LAYER2_TRACE_MARKER currently depends on one exact quoted trace literal. A regex-based check for the semantic condition (minimal profile comparison) would reduce false negatives across environments.

Proposed robust matcher
-const LAYER2_TRACE_MARKER = "'[' minimal = minimal ']'";
+const LAYER2_TRACE_RE = /\[\s+minimal\s+=\s+minimal\s+\]/;
...
-    result.stderr.includes(LAYER2_TRACE_MARKER),
-    `entrypoint ${entrypoint} should reach Layer 2 (expected ${LAYER2_TRACE_MARKER} in trace); stderr tail: ${result.stderr.slice(-400)}`
+    LAYER2_TRACE_RE.test(result.stderr),
+    `entrypoint ${entrypoint} should reach Layer 2 (expected minimal-profile check in trace); stderr tail: ${result.stderr.slice(-400)}`
...
-    !result.stderr.includes(LAYER2_TRACE_MARKER),
-    `entrypoint ${entrypoint} should stop at Layer 1 (Layer 2 marker ${LAYER2_TRACE_MARKER} should NOT appear); stderr tail: ${result.stderr.slice(-400)}`
+    !LAYER2_TRACE_RE.test(result.stderr),
+    `entrypoint ${entrypoint} should stop at Layer 1 (Layer 2 marker should NOT appear); stderr tail: ${result.stderr.slice(-400)}`

Also applies to: 126-127

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/hooks/observe-entrypoint-allowlist.test.js` around lines 103 - 114, The
current brittle LAYER2_TRACE_MARKER string check in assertAllowedReachesLayer2
should be replaced with a regex-based assertion that matches the semantic
"minimal = minimal" comparison across varying xtrace formats; update the code in
assertAllowedReachesLayer2 (and the analogous check at lines ~126-127) to build
a RegExp like /\bminimal\s*=\s*minimal\b/ (allowing optional surrounding
brackets/quotes and whitespace) and assert that result.stderr.match(...) is
truthy so the test is robust across Bash/xtrace variations; keep runObserve
usage and error messages but swap the exact-string include checks for the regex
match.

43-47: ⚡ Quick win

Replace direct console.log usage in the edited test file.

Line 43, Line 46-47, Line 131, and Line 148-149 use console.log. Please switch to a test logger/helper (or process.stdout.write) so this follows repository JS logging rules consistently.

As per coding guidelines, "Warn about console.log statements in edited files".

Also applies to: 131-132, 148-149

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/hooks/observe-entrypoint-allowlist.test.js` around lines 43 - 47,
Replace direct console.log calls used in the test's try/catch reporter (the
lines that print `  ✓ ${name}`, `  ✗ ${name}`, and the error message using
`err.message`) with the project's test logger or process.stdout.write; locate
the usages that reference the local variables `name`, `passed`, and `err` and
swap each console.log to the shared test logging helper (or call
process.stdout.write with the same formatted strings) so logging follows
repository JS logging rules across all occurrences in this test.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/hooks/observe-entrypoint-allowlist.test.js`:
- Around line 57-61: The empty catch around fs.rmSync(dir, { recursive: true,
force: true }) swallows cleanup errors; update the catch to explicitly handle
and surface failures (e.g., log with console.error or the test logger) including
the directory name and error object so failures are diagnosable, or rethrow if
appropriate for the test; locate the try/catch that wraps fs.rmSync for variable
dir in tests/hooks/observe-entrypoint-allowlist.test.js and replace the silent
ignore with an explicit error handling statement that records the error details.
- Around line 103-114: The current brittle LAYER2_TRACE_MARKER string check in
assertAllowedReachesLayer2 should be replaced with a regex-based assertion that
matches the semantic "minimal = minimal" comparison across varying xtrace
formats; update the code in assertAllowedReachesLayer2 (and the analogous check
at lines ~126-127) to build a RegExp like /\bminimal\s*=\s*minimal\b/ (allowing
optional surrounding brackets/quotes and whitespace) and assert that
result.stderr.match(...) is truthy so the test is robust across Bash/xtrace
variations; keep runObserve usage and error messages but swap the exact-string
include checks for the regex match.
- Around line 43-47: Replace direct console.log calls used in the test's
try/catch reporter (the lines that print `  ✓ ${name}`, `  ✗ ${name}`, and the
error message using `err.message`) with the project's test logger or
process.stdout.write; locate the usages that reference the local variables
`name`, `passed`, and `err` and swap each console.log to the shared test logging
helper (or call process.stdout.write with the same formatted strings) so logging
follows repository JS logging rules across all occurrences in this test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c9e4b598-50f4-4623-9044-4304c1a3cbd1

📥 Commits

Reviewing files that changed from the base of the PR and between 0f84c0e and 08aacc8.

📒 Files selected for processing (2)
  • skills/continuous-learning-v2/hooks/observe.sh
  • tests/hooks/observe-entrypoint-allowlist.test.js

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 2 files

Re-trigger cubic

@affaan-m
affaan-m merged commit 30ef079 into affaan-m:main Jun 7, 2026
40 checks passed
syarfandi pushed a commit to syarfandi/ECC that referenced this pull request Jun 9, 2026
…affaan-m#2134)

The observe.sh Layer 1 entrypoint guard short-circuits with exit 0 when
CLAUDE_CODE_ENTRYPOINT is not in {cli, sdk-ts, claude-desktop}. Claude
Code's VS Code extension sets CLAUDE_CODE_ENTRYPOINT=claude-vscode, so
VS Code users see no observations recorded — observations.jsonl never
gets created and the instinct pipeline stays empty.

Add claude-vscode to the allowlist, mirroring the precedent in affaan-m#1522
which added claude-desktop the same way.

Add a regression test that spawns observe.sh under bash -x for each
allowed entrypoint (cli, sdk-ts, claude-desktop, claude-vscode) and
each denied entrypoint (unknown-host, claude-cody, mcp), asserting
that allowed entrypoints reach Layer 2's ECC_HOOK_PROFILE check while
denied entrypoints stop at Layer 1.

Fixes affaan-m#2102
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.

observe.sh silently exits on VS Code extension (CLAUDE_CODE_ENTRYPOINT=claude-vscode)

2 participants