Skip to content

Add package boundary check + migrate LocalNet to canton-dev-tools (ENG-1635) - #451

Merged
HardlyDifficult merged 6 commits into
mainfrom
cursor/sdk-boundary-audit-5279
Aug 10, 2026
Merged

Add package boundary check + migrate LocalNet to canton-dev-tools (ENG-1635)#451
HardlyDifficult merged 6 commits into
mainfrom
cursor/sdk-boundary-audit-5279

Conversation

@HardlyDifficult

@HardlyDifficult HardlyDifficult commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Hard cutover to published @fairmint/canton-dev-tools@0.1.1 (npm — not github:Fairmint/canton-dev-tools#…):

  • Keep the npm package-boundary / pack-guard work already on this PR (check:package-artifacts, CI + publish wiring)
  • Add @fairmint/canton-dev-tools@0.1.1 as a devDependency
  • Rewire all localnet* scripts from canton-localnetcanton-dev-tools
  • Remove the stale config.localnet_quickstart_ref override (5c90cf4d…) so Dev Tools pins apply
  • Delete test/utils/testConfig.ts; import from @fairmint/canton-dev-tools/testing (shared-secret env shim for OCP CI)
  • Keep OCP-specific transactionHelpers / integration harness

Part of ENG-1635. Companion docs: https://github.com/Fairmint/dev-docs/pull/29. Node-sdk hard cutover (~2k LOC deleted): Fairmint/canton-node-sdk#398.

Test plan

  • npm install --legacy-peer-deps
  • npm run build
  • npm run typecheck
  • npm test (2811 tests)
  • npm run check:package-artifacts
  • CI green on this PR
  • LocalNet smoke / integration when Docker available (npm run localnet:verify)

Note

Medium Risk
Touches npm publish gates and LocalNet/CI integration auth; runtime SDK API is unchanged, and the pack guard reduces accidental leakage of non-dist files.

Overview
Adds npm run check:package-artifacts and runs it in CI and publish after build. The script dry-runs npm pack, enforces that only dist/** plus standard npm metadata ship, requires core entrypoints and dist/ocf-schema/objects, and caps unpacked size (configurable via MAX_PACKAGE_UNPACKED_BYTES). Unit tests cover the validator.

LocalNet / integration moves from canton-localnet to @fairmint/canton-dev-tools@0.1.1: localnet* scripts invoke canton-dev-tools with shared-secret env, drops config.localnet_quickstart_ref, and bumps @fairmint/canton-node-sdk. In-repo test/utils/testConfig.ts is removed; integration tests and quickstart scripts use @fairmint/canton-dev-tools/testing, with setupSharedSecretEnv.ts wired into jest.integration.config.js so OCP CI keeps shared-secret auth and OCP_TEST_AUTH_MODE. jsonwebtoken is dropped as a dev dependency. The QuickStart workflow uses Node 22.

Reviewed by Cursor Bugbot for commit afd7983. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • New Features

    • Added automated validation to ensure published packages contain only expected files, required runtime assets, and schemas.
    • Added shared-secret authentication support for local development and integration testing.
  • Bug Fixes

    • Added package validation to continuous integration and publishing workflows to prevent incomplete or oversized packages from being released.
  • Tests

    • Added coverage for package contents, required artifacts, unexpected files, and package size limits.
    • Standardized integration testing configuration through shared development tools.

ENG-1635: guard that only dist/** ships (no LocalNet CLI, DARs, or libs).

Co-authored-by: HardlyDifficult <hardlydiff@gmail.com>
Copilot AI balanced review requested due to automatic review settings August 10, 2026 17:13
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The pull request adds npm package artifact validation to CI and publishing workflows. It also migrates integration tooling to Canton development tools and configures shared-secret authentication for LocalNet tests.

Changes

Package artifact validation

Layer / File(s) Summary
Package artifact validation
scripts/check-package-artifacts.cjs, test/scripts/checkPackageArtifacts.test.ts
The validator checks npm pack metadata, package size, required runtime files, schemas, and allowed paths. Tests cover valid and invalid package contents.
Npm, CI, and publish integration
package.json, .github/workflows/ci.yml, .github/workflows/publish.yml
package.json adds the validation command. CI and publishing run it before release completion.

Shared-secret test tooling

Layer / File(s) Summary
Development tools migration
package.json, tsconfig.tests.json, test/integration/quickstart.smoke.test.ts, test/integration/setup/integrationTestHarness.ts
The LocalNet command and integration clients use @fairmint/canton-dev-tools/testing. The Canton node SDK is upgraded.
Shared-secret environment setup
test/integration/setupSharedSecretEnv.ts, jest.integration.config.js, scripts/quickstart/waitForReady.ts
Test setup initializes FAIRMINT_TEST_SHARED_SECRET from OCP_TEST_SHARED_SECRET or unsafe before client creation.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 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 (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies both main changes: package-boundary validation and the LocalNet migration to canton-dev-tools.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/sdk-boundary-audit-5279

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@scripts/check-package-artifacts.cjs`:
- Around line 77-89: Update the package path validation around packagePaths and
forbiddenPackagePathReason to enforce an allowlist: accept only paths under
dist/ and the explicit required npm metadata files, rejecting every other
packaged path. Preserve the existing required runtime entry checks, and add a
requirement for at least one file under dist/ocf-schema when that runtime
directory is needed.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: be79d325-5a33-40d0-b386-f4c82a823ab5

📥 Commits

Reviewing files that changed from the base of the PR and between ea4ad73 and a59e40a.

📒 Files selected for processing (3)
  • .github/workflows/ci.yml
  • package.json
  • scripts/check-package-artifacts.cjs

Comment thread scripts/check-package-artifacts.cjs Outdated

Copilot AI 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.

Pull request overview

Adds an npm packaging guard to prevent repository-only artifacts from entering the published SDK.

Changes:

  • Validates npm pack contents, size, and required entry points.
  • Exposes the validator through an npm script.
  • Runs validation after CI builds.

Reviewed changes

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

File Description
scripts/check-package-artifacts.cjs Implements package validation.
package.json Adds the validation command.
.github/workflows/ci.yml Runs validation in CI.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread scripts/check-package-artifacts.cjs Outdated
Comment thread scripts/check-package-artifacts.cjs Outdated
Comment thread scripts/check-package-artifacts.cjs Outdated
Switch the publish boundary guard from a denylist to an allowlist of
dist/** plus npm metadata, require packaged dist/ocf-schema objects,
and add table-driven rejection tests.

Co-authored-by: HardlyDifficult <hardlydiff@gmail.com>
Copilot AI review requested due to automatic review settings August 10, 2026 17:46

Copilot AI 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.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Suppressed comments (2)

scripts/check-package-artifacts.cjs:89

  • This only proves that one arbitrary file exists below objects/. A package containing only dist/ocf-schema/objects/Issuer.schema.json (the positive test fixture) passes, while exported runtime APIs support dozens of paths from OCF_OBJECT_SCHEMA_PATHS and will throw when any requested schema or referenced schema is absent. Validate the complete runtime-required schema set (including referenced schemas), not just that the directory is non-empty.
    const hasOcfSchemaObjects = [...packagePaths].some((packagePath) =>
      packagePath.startsWith('dist/ocf-schema/objects/')
    );

scripts/check-package-artifacts.cjs:38

  • npm-packlist always includes root COPYING files, but this exact-name set does not recognize them. Adding standard legal metadata such as COPYING would therefore make this boundary check fail even though npm includes it regardless of files. Recognize npm's README/license/licence/copying family case-insensitively rather than relying only on the enumerated variants.

This issue also appears on line 87 of the same file.

  if (ALLOWED_NPM_METADATA_FILES.has(packagePath)) return true;

Comment thread .github/workflows/ci.yml
Run check:package-artifacts in publish.yml after prepare-release so the
release artifact is validated before npm publish.

Co-authored-by: HardlyDifficult <hardlydiff@gmail.com>
Copilot AI review requested due to automatic review settings August 10, 2026 17:51

Copilot AI 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.

Pull request overview

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

Rewire localnet* scripts to canton-dev-tools, drop the stale Quickstart
pin override so Dev Tools defaults apply, and replace local testConfig
helpers with @fairmint/canton-dev-tools/testing while keeping OCP-specific
transaction helpers and the package-boundary pack guard.

Co-authored-by: HardlyDifficult <hardlydiff@gmail.com>
Copilot AI review requested due to automatic review settings August 10, 2026 21:05
@HardlyDifficult HardlyDifficult changed the title Add npm package boundary check (ENG-1635) Add package boundary check + migrate LocalNet to canton-dev-tools (ENG-1635) Aug 10, 2026

Copilot AI 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.

Pull request overview

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

Comment thread package.json
"lint": "eslint . --max-warnings=0",
"lint:fix": "eslint . --fix --max-warnings=0",
"localnet": "CANTON_LOCALNET_AUTH_MODE=shared-secret CANTON_LOCALNET_QUICKSTART_REF=$npm_package_config_localnet_quickstart_ref canton-localnet",
"localnet": "CANTON_LOCALNET_AUTH_MODE=shared-secret FAIRMINT_TEST_SHARED_SECRET=unsafe canton-dev-tools",

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in afd7983test-ocp-quickstart.yml now uses Node 22 to match @fairmint/canton-dev-tools engines.

Comment thread package.json
"devDependencies": {
"@apidevtools/json-schema-ref-parser": "15.3.5",
"@eslint/eslintrc": "3.3.5",
"@fairmint/canton-dev-tools": "0.1.1",

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Already addressed on this branch — @fairmint/canton-node-sdk is pinned to 0.0.232 in devDependencies (satisfies the Dev Tools peer). No further change needed.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@test/integration/setupSharedSecretEnv.ts`:
- Around line 8-11: Update the shared-secret setup near
FAIRMINT_TEST_SHARED_SECRET to also set OCP_TEST_AUTH_MODE to the shared-secret
mode used by integrationTestHarness.ts, ensuring client construction and
ledger-api-user rights setup use the same authentication source.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 24f30cf4-801f-4eab-b9a9-7778c03b764f

📥 Commits

Reviewing files that changed from the base of the PR and between a59e40a and b764310.

📒 Files selected for processing (11)
  • .github/workflows/publish.yml
  • jest.integration.config.js
  • package.json
  • scripts/check-package-artifacts.cjs
  • scripts/quickstart/waitForReady.ts
  • test/integration/quickstart.smoke.test.ts
  • test/integration/setup/integrationTestHarness.ts
  • test/integration/setupSharedSecretEnv.ts
  • test/scripts/checkPackageArtifacts.test.ts
  • test/utils/testConfig.ts
  • tsconfig.tests.json
💤 Files with no reviewable changes (1)
  • test/utils/testConfig.ts

Comment thread test/integration/setupSharedSecretEnv.ts
@fairmint/canton-dev-tools@0.1.1 requires peer @fairmint/canton-node-sdk
>=0.0.232; CI npm install failed on the prior 0.0.227 pin.

Co-authored-by: HardlyDifficult <hardlydiff@gmail.com>
Copilot AI review requested due to automatic review settings August 10, 2026 21:15

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
package.json (1)

49-49: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Preserve the shared-secret override semantics.

The localnet command overwrites an existing FAIRMINT_TEST_SHARED_SECRET with unsafe. Use a fallback assignment instead. The logs argument is supported by canton-dev-tools.

🤖 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 `@package.json` at line 49, Update the localnet script’s
FAIRMINT_TEST_SHARED_SECRET assignment to set unsafe only when the variable is
not already defined, preserving caller-provided secrets while keeping
canton-dev-tools and its logs argument behavior unchanged.
🤖 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.

Outside diff comments:
In `@package.json`:
- Line 49: Update the localnet script’s FAIRMINT_TEST_SHARED_SECRET assignment
to set unsafe only when the variable is not already defined, preserving
caller-provided secrets while keeping canton-dev-tools and its logs argument
behavior unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: bc032eaf-703b-4bfe-b32c-6b813da4fc3c

📥 Commits

Reviewing files that changed from the base of the PR and between b764310 and b9394a7.

📒 Files selected for processing (1)
  • package.json

Copilot AI 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.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated no new comments.

Suppressed comments (3)

package.json:81

  • @fairmint/canton-dev-tools@0.1.1 declares Node >=22, but .github/workflows/test-ocp-quickstart.yml:20-23 still provisions Node 20 for the workflow that installs this dependency and invokes its CLI/testing entrypoint. The LocalNet verification therefore runs on an unsupported runtime and emits an engine mismatch; update that workflow to Node 22 as part of this cutover.
    "@fairmint/canton-dev-tools": "0.1.1",

test/integration/setupSharedSecretEnv.ts:8

  • ??= leaves an explicitly empty FAIRMINT_TEST_SHARED_SECRET untouched, while Dev Tools treats an empty value as unset. The helper then sees no shared-secret override and falls back to OAuth2 against this shared-secret LocalNet profile. Use ||= so empty variables receive the OCP secret or unsafe fallback too.
process.env.FAIRMINT_TEST_SHARED_SECRET ??=

scripts/quickstart/waitForReady.ts:15

  • ??= does not replace an explicitly empty FAIRMINT_TEST_SHARED_SECRET, but Dev Tools ignores empty values. In that case waitForLedgerJsonApiReady() constructs an OAuth2 config even though this script targets the shared-secret LocalNet profile. Use ||= to preserve non-empty overrides while treating an empty variable as unset.
  process.env.FAIRMINT_TEST_SHARED_SECRET ??=

@HardlyDifficult
HardlyDifficult requested a balanced review from Copilot August 10, 2026 21:42
@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

@copilot review

@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

@cursor review

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Already reviewed.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cursor cursor 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.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit b9394a7. Configure here.

Copilot AI 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.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Comment on lines +87 to +88
const hasOcfSchemaObjects = [...packagePaths].some((packagePath) =>
packagePath.startsWith('dist/ocf-schema/objects/')

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Deferring a full packed-vs-source schema manifest equality check for a follow-up. This PR already requires dist/ocf-schema/** plus at least one objects/ schema; the copy step publishes the complete tree and CI check:package-artifacts is green. Expanding to exact path-set equality is valuable but out of scope for the ENG-1635 LocalNet cutover.

Co-authored-by: HardlyDifficult <hardlydiff@gmail.com>
Copilot AI review requested due to automatic review settings August 10, 2026 21:49

Copilot AI 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.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.

@HardlyDifficult
HardlyDifficult merged commit ba4de43 into main Aug 10, 2026
8 checks passed
@HardlyDifficult
HardlyDifficult deleted the cursor/sdk-boundary-audit-5279 branch August 10, 2026 21:59
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.

3 participants