Skip to content

feat: implement compute profile detection and default tool policy#26

Closed
anand-testcompare wants to merge 5 commits into
mainfrom
22-compute-module-profile-detection-and-default-tool-policy
Closed

feat: implement compute profile detection and default tool policy#26
anand-testcompare wants to merge 5 commits into
mainfrom
22-compute-module-profile-detection-and-default-tool-policy

Conversation

@anand-testcompare
Copy link
Copy Markdown
Owner

@anand-testcompare anand-testcompare commented Feb 16, 2026

Summary

  • add compute-module-aware profile taxonomy (compute_modules, compute_modules_ts, compute_modules_py) and deterministic repo-scan scoring with reason traces
  • centralize profile defaults into discoverable policy modules under src/palantir-mcp/profiles/ and switch tool gating to policy-driven broad defaults with a minimal destructive deny list
  • add profile override support for setup/rescan (--profile, plus env fallback) with explicit output showing selected profile, detected profile, and policy summary
  • default agent.foundry.mode to all when unset across config hook + setup/rescan/bootstrap flows while preserving explicit user mode values
  • add/expand tests for detector behavior, policy behavior, override precedence, mode defaults, and setup/rescan/bootstrap preservation semantics

Validation

  • mise run format
  • mise run lint
  • mise run typecheck
  • mise run build
  • mise run test
  • external regression (copy/link workflow in another repo):
    • bun run scripts/dev/link-into-repo.ts --target /tmp/opencode-regression-1771222961 --source dist
    • bun run scripts/dev/run-opencode-command.ts --repo /tmp/opencode-regression-1771222961 --command setup-palantir-mcp --args "$FOUNDRY_URL --profile compute_modules_ts"
    • bun run scripts/dev/run-opencode-command.ts --repo /tmp/opencode-regression-1771222961 --command rescan-palantir-mcp-tools --args "--profile compute_modules"

Notes

  • mise run smoke still fails in this environment because the local docs snapshot has too few indexed pages (list_all_docs returned only 0 pages, expected 3000+).

Closes #22

Summary by CodeRabbit

  • New Features

    • New repository profiles (compute_modules + TS/Python variants, pipelines, OSDK, mixed/unknown) with policy metadata and denied-tools preview
    • Profile-aware setup/rescan with --profile flag, env overrides, enhanced summaries showing selected profile, source, detection reasons, and policy preview
    • Improved repository scanning and scoring for profile detection; profile-aware allowlist computation
  • Bug Fixes

    • Foundry agent now defaults to "all" when unspecified; explicit foundry mode preserved
    • Tool availability toggles corrected
  • Tests

    • Extensive new and updated tests for profiles, mode preservation, scanning, CLI and rescan behaviors

@anand-testcompare anand-testcompare linked an issue Feb 16, 2026 that may be closed by this pull request
6 tasks
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 16, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds centralized profile-policy infra and compute-module detection, introduces CLI/env profile override parsing and profile-aware flows, defaults unset agent.foundry.mode to "all" (preserving explicit values), computes profile-driven allowlists, and propagates profile into setup/rescan/bootstrap patching and summaries.

Changes

Cohort / File(s) Summary
Profiles & Types
src/palantir-mcp/profiles/... (policy-types.ts, shared.ts, compute-modules.ts, compute-modules-ts.ts, compute-modules-py.ts, pipelines-transforms.ts, osdk-functions-ts.ts, all.ts, unknown.ts, index.ts), src/palantir-mcp/types.ts
Add profile policy types and factory, multiple profile modules (compute_modules*, pipelines/transforms, osdk, all, unknown), policy registry (getProfilePolicy), expand ProfileId and PROFILE_IDS.
Repo Scanning
src/palantir-mcp/repo-scan.ts
Add compute-module signal detection (package.json/pyproject/requirements/scripts/paths), language-aware scoring (TS vs Python), new compute profile outcomes, and add PackageJson.scripts typing.
Allowlist & Policy Eval
src/palantir-mcp/allowlist.ts
Refactor allowlist computation to policy-driven evaluation; add ComputedAllowlist.policy metadata and deniedTools; introduce matching/evaluation helpers.
Commands / CLI & Integration
src/palantir-mcp/commands.ts, src/index.ts
Add CLI arg tokenization and env override parsing, profile resolution types/flows, pass resolved profile into patch creation/summary, update setupPalantirMcp / rescanPalantirMcpTools to accept profile/rawArgs, and surface profile resolution in output.
Opencode Config Defaults
src/palantir-mcp/opencode-config.ts, src/__tests__/autoBootstrap.test.ts, src/__tests__/configHook.test.ts
Change defaulting: non-string/absent agent.mode'all' for foundry, 'subagent' otherwise; preserve explicit modes. Tests updated to assert mode behavior.
Tests — Detection, Policy & Flows
src/__tests__/repoScan.test.ts, src/__tests__/profilePolicy.test.ts, src/__tests__/palantirMcpSetup.test.ts, src/__tests__/palantirMcpRescan.test.ts, src/__tests__/autoBootstrap.test.ts, src/__tests__/configHook.test.ts
Add repo-scan tests for TS/Py/mixed/unknown; policy tests for allowed/denied tools; extend setup/rescan/bootstrap tests for profile override, reporting, default modes, and preservation of explicit foundry.mode; minor test refactors and expectations.
Docs / Misc & Typings
src/docs/snapshot.ts, src/index.ts
Minor typing change for Stats import; update command descriptions to show --profile flag and pass hook arguments into setup/rescan call sites.
Allowlist Consumers / API surface
src/palantir-mcp/commands.ts, src/palantir-mcp/allowlist.ts
ComputedAllowlist includes policy and deniedTools; formatPatchSummary signature updated to accept ProfileResolution and ComputedAllowlist; functions updated to propagate profile resolution.

Sequence Diagram

sequenceDiagram
    rect rgba(220,220,255,0.5)
    participant User
    end
    rect rgba(200,255,200,0.5)
    participant CLI as CLI (index.ts)
    end
    participant RepoScan as RepoScan
    participant Resolver as ProfileResolver
    participant Policy as PolicyRegistry
    participant Allowlist as AllowlistEngine
    participant Patcher as ConfigPatcher
    participant Output as Summary

    User->>CLI: run setup/rescan (optional --profile / env)
    CLI->>RepoScan: scanRepoForProfile(worktree)
    RepoScan-->>CLI: detectedProfile + reasons
    CLI->>Resolver: resolveProfileOverride(cliArgs, env, detectedProfile)
    Resolver-->>CLI: ProfileResolution (selected, source, reasons)
    CLI->>Policy: getProfilePolicy(selectedProfile)
    Policy-->>CLI: ProfilePolicy (librarian/foundry rules)
    CLI->>Allowlist: computeAllowedTools(discoveredTools, policy)
    Allowlist-->>CLI: ComputedAllowlist (allows, deniedTools, policy)
    CLI->>Patcher: create/patch config (apply mode defaults, preserve explicit)
    Patcher-->>CLI: PatchResult
    CLI->>Output: formatPatchSummary(PatchResult, ProfileResolution, ComputedAllowlist)
    Output-->>User: Summary (selected profile, source, reasons, policy preview)
Loading

Possibly related PRs

Poem

🐰
I nibbled logs and chased each regex bloom,
Found profiles hiding in the repo's room,
When foundry slept, I set its mode to "all",
Kept your choices safe, and heard the policy call,
Hopping off—patches stitched, the defaults bloom.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main feature: implementing compute profile detection and default tool policy, matching the primary changes throughout the PR.
Linked Issues check ✅ Passed The PR comprehensively addresses all coding requirements from issue #22: adds compute-module profile taxonomy with detection heuristics, centralizes profile policies in src/palantir-mcp/profiles/, implements profile override support with clear precedence, sets foundry.mode default to 'all', switches to policy-driven broad defaults with minimal deny list, and includes extensive tests for detector behavior, policy enforcement, override precedence, and mode preservation semantics.
Out of Scope Changes check ✅ Passed All changes are directly in scope: profile taxonomy extensions (types.ts, new profile modules), detection heuristics (repo-scan.ts), override and output handling (commands.ts), mode defaults (opencode-config.ts, autoBootstrap), tool policy refactoring (allowlist.ts), and comprehensive test coverage for related functionality. No unrelated changes detected.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

✏️ 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 22-compute-module-profile-detection-and-default-tool-policy

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

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 (2)
src/palantir-mcp/types.ts (1)

20-28: Consider simplifying parseProfileId using the PROFILE_IDS constant.

The function repeats each profile ID value that's already defined in PROFILE_IDS. This could be simplified to reduce duplication and ensure consistency.

♻️ Optional simplification
 export function parseProfileId(value: unknown): ProfileId | null {
-  if (value === 'compute_modules') return value;
-  if (value === 'compute_modules_ts') return value;
-  if (value === 'compute_modules_py') return value;
-  if (value === 'pipelines_transforms') return value;
-  if (value === 'osdk_functions_ts') return value;
-  if (value === 'all') return value;
-  if (value === 'unknown') return value;
-  return null;
+  if (typeof value === 'string' && PROFILE_IDS.includes(value as ProfileId)) {
+    return value as ProfileId;
+  }
+  return null;
 }
src/index.ts (1)

68-83: Consider splitting long description strings.

Lines 72 and 80 contain description strings that exceed the 100-character line width guideline. While Prettier typically doesn't auto-split string literals, consider using array join for readability:

♻️ Suggested refactor for line width
     if (!cfg.command['setup-palantir-mcp']) {
       cfg.command['setup-palantir-mcp'] = {
         template: 'Set up palantir-mcp for this repo.',
         description:
-          'Guided MCP setup for Foundry. Usage: /setup-palantir-mcp <foundry_api_url> [--profile <profile_id>]. Requires FOUNDRY_TOKEN for tool discovery.',
+          'Guided MCP setup for Foundry. ' +
+          'Usage: /setup-palantir-mcp <foundry_api_url> [--profile <profile_id>]. ' +
+          'Requires FOUNDRY_TOKEN for tool discovery.',
       };
     }

     if (!cfg.command['rescan-palantir-mcp-tools']) {
       cfg.command['rescan-palantir-mcp-tools'] = {
         template: 'Re-scan palantir-mcp tools and patch tool gating.',
         description:
-          'Re-discovers the palantir-mcp tool list and adds missing palantir-mcp_* toggles (does not overwrite existing toggles). Usage: /rescan-palantir-mcp-tools [--profile <profile_id>]. Requires FOUNDRY_TOKEN.',
+          'Re-discovers the palantir-mcp tool list and adds missing palantir-mcp_* toggles ' +
+          '(does not overwrite existing toggles). ' +
+          'Usage: /rescan-palantir-mcp-tools [--profile <profile_id>]. Requires FOUNDRY_TOKEN.',
       };
     }

Comment thread src/palantir-mcp/commands.ts Outdated
`Valid profile IDs: ${formatProfileChoices()}`,
'',
'Example:',
' /setup-palantir-mcp https://23dimethyl.usw-3.palantirfoundry.com --profile compute_modules_ts',
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

replace with something else thts not mine, make the example funny.. easter egg

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Updated in cae2bde with a non-personal easter-egg URL: https://totally-not-skynet.palantirfoundry.com.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Updated again in 764299a to a more unhinged pun: https://who-let-the-dag-out.palantirfoundry.com.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Updated per request in 587cddc: https://buschlightdid911.usw-3.palantirfoundry.com.

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.

🤖 Fix all issues with AI agents
Verify each finding against the current code and only fix it if needed.


In `@src/palantir-mcp/commands.ts`:
- Around line 121-196: Both parseSetupArgs and parseRescanArgs duplicate the
same --profile parsing logic; extract that logic into a small helper (e.g.,
parseProfileFlag) that accepts the token array and current index (or returns a
tuple of {value, consumed, error}) and reuse it from both functions; update
parseSetupArgs and parseRescanArgs to call tokenizeArgs, invoke the new
parseProfileFlag when encountering '--profile' or '--profile=', handle returned
errors/consumed count, and preserve existing positional-argument behaviors in
parseSetupArgs (single Foundry URL) and parseRescanArgs (no positional args).
- Around line 113-119: The tokenizeArgs function contains a redundant .map((t)
=> t.trim()) because splitting with /\s+/ already strips inter-token whitespace;
update the function tokenizeArgs to remove the unnecessary map step and simply
trim the input, split on /\s+/ and filter out empty tokens (i.e., keep the
.trim(), .split(/\s+/g) and .filter((t) => t.length > 0) but drop the .map
call).
🧹 Nitpick comments (2)
🤖 Fix all nitpicks with AI agents
Verify each finding against the current code and only fix it if needed.


In `@src/palantir-mcp/commands.ts`:
- Around line 121-196: Both parseSetupArgs and parseRescanArgs duplicate the
same --profile parsing logic; extract that logic into a small helper (e.g.,
parseProfileFlag) that accepts the token array and current index (or returns a
tuple of {value, consumed, error}) and reuse it from both functions; update
parseSetupArgs and parseRescanArgs to call tokenizeArgs, invoke the new
parseProfileFlag when encountering '--profile' or '--profile=', handle returned
errors/consumed count, and preserve existing positional-argument behaviors in
parseSetupArgs (single Foundry URL) and parseRescanArgs (no positional args).
- Around line 113-119: The tokenizeArgs function contains a redundant .map((t)
=> t.trim()) because splitting with /\s+/ already strips inter-token whitespace;
update the function tokenizeArgs to remove the unnecessary map step and simply
trim the input, split on /\s+/ and filter out empty tokens (i.e., keep the
.trim(), .split(/\s+/g) and .filter((t) => t.length > 0) but drop the .map
call).
src/palantir-mcp/commands.ts (2)

121-196: Consider extracting shared --profile parsing logic.

Both parseSetupArgs and parseRescanArgs contain identical logic for handling --profile and --profile= flags (lines 128-143 and 168-183). While the functions have different positional argument requirements, the profile parsing could be extracted into a shared helper to reduce duplication.

This is a low-priority refactor given the functions are readable and the duplication is contained.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/palantir-mcp/commands.ts` around lines 121 - 196, Both parseSetupArgs and
parseRescanArgs duplicate the same --profile parsing logic; extract that logic
into a small helper (e.g., parseProfileFlag) that accepts the token array and
current index (or returns a tuple of {value, consumed, error}) and reuse it from
both functions; update parseSetupArgs and parseRescanArgs to call tokenizeArgs,
invoke the new parseProfileFlag when encountering '--profile' or '--profile=',
handle returned errors/consumed count, and preserve existing positional-argument
behaviors in parseSetupArgs (single Foundry URL) and parseRescanArgs (no
positional args).

113-119: Minor: Redundant .map((t) => t.trim()) after whitespace split.

Splitting on /\s+/g won't produce tokens with leading/trailing whitespace, making the .map((t) => t.trim()) call redundant.

♻️ Suggested simplification
 function tokenizeArgs(rawArgs: string): string[] {
   return rawArgs
     .trim()
     .split(/\s+/g)
-    .map((t) => t.trim())
     .filter((t) => t.length > 0);
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/palantir-mcp/commands.ts` around lines 113 - 119, The tokenizeArgs
function contains a redundant .map((t) => t.trim()) because splitting with /\s+/
already strips inter-token whitespace; update the function tokenizeArgs to
remove the unnecessary map step and simply trim the input, split on /\s+/ and
filter out empty tokens (i.e., keep the .trim(), .split(/\s+/g) and .filter((t)
=> t.length > 0) but drop the .map call).

@anand-testcompare anand-testcompare deleted the 22-compute-module-profile-detection-and-default-tool-policy branch February 18, 2026 15:25
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.

Foundry defaults: hard-signature profiles and unified default policy

1 participant