Skip to content

fix: harden package entrypoint and validation gates - #634

Merged
kang-heewon merged 1 commit into
trunkfrom
fix/618-package-entrypoint-contracts
Jun 14, 2026
Merged

fix: harden package entrypoint and validation gates#634
kang-heewon merged 1 commit into
trunkfrom
fix/618-package-entrypoint-contracts

Conversation

@kang-heewon

@kang-heewon kang-heewon commented Jun 14, 2026

Copy link
Copy Markdown
Member

Summary

Public package publish manifests now have a checked entrypoint contract, and the validation path now ignores generated formatter targets so release and CI gates fail on actionable source drift instead of generated artifacts.

Fixes #618

변경 사항

  • Public package manifests are normalized around a documented policy: workspace source entrypoints can remain local, while publishConfig is the authoritative dist-based npm contract.
  • pnpm package-manifests:check now fails manifest drift, and pnpm package-manifests:write preserves package versions while normalizing the contract.
  • CI and release workflows now run the manifest gate, and CI/release also verify a representative CJS, ESM, and TypeScript consumer entrypoint smoke.
  • Generated API docs, CI reports, OWX runtime state, and the single-quote normalize-package test are excluded from repo-wide oxfmt checks through the shared formatter ignore path.
  • The pre-commit oxfmt hook now uses the same ignore paths as pnpm check and pnpm format.
  • package-entrypoint-smoke now bounds child process execution and reports spawn errors explicitly.
  • Container.remove() now unregisters constructor component metadata so validation and later resolution honor removed components.
  • The rpc-codegen e2e test now has an explicit timeout for slower CI runners.
  • Changesets are included for the public packages whose manifests changed and for the framework-context removal behavior.

Verification

  • pnpm install --frozen-lockfile
  • pnpm check
  • pnpm exec vitest run scripts/tests/normalize-packages.spec.ts
  • pnpm --filter @croco/framework-context test
  • pnpm --filter @croco/framework-context typecheck
  • pnpm --filter @croco/rpc-codegen test
  • pnpm build
  • pnpm typecheck
  • pnpm package-entrypoints:smoke
  • pnpm test
  • pnpm pack manifest check for @croco/framework-context

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@kang-heewon, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 19 minutes and 49 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: fa4ee261-b0a9-422c-8c54-2e97af330dcd

📥 Commits

Reviewing files that changed from the base of the PR and between e54f752 and 2f92b43.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (26)
  • .changeset/framework-context-container-remove.md
  • .changeset/package-entrypoint-contracts.md
  • .github/workflows/ci.yml
  • .github/workflows/release.yml
  • .oxfmtignore
  • docs/release/package-entrypoint-contract.md
  • lefthook.yaml
  • package.json
  • packages/access-drizzle/package.json
  • packages/auth-drizzle/package.json
  • packages/cli/package.json
  • packages/cli/tsup.config.ts
  • packages/docs/package.json
  • packages/docs/src/content/docs/api/problems-core/src/classes/Problem.md
  • packages/docs/tsconfig.typedoc.json
  • packages/framework-context/src/libs/Container.ts
  • packages/impersonation-core/package.json
  • packages/llm-core/package.json
  • packages/llm-metering/package.json
  • packages/rpc-codegen/src/tests/e2e.spec.ts
  • packages/search-core/package.json
  • packages/search-drizzle/package.json
  • packages/search-meilisearch/package.json
  • scripts/normalize-packages.mjs
  • scripts/package-entrypoint-smoke.mts
  • scripts/tests/normalize-packages.spec.ts
📝 Walkthrough

Walkthrough

normalize-packages.mjs--check/--write 모드를 지원하는 배포 계약 정규화 CLI로 전환하고, 여러 @croco/* 패키지의 package.jsonsrc 기반 main/typesdist 기반 publishConfig를 적용하며, 스모크 테스트 스크립트, 통합 테스트, CI 게이트 단계, 배포 계약 문서를 추가한다.

Changes

패키지 엔트리포인트 계약 표준화

Layer / File(s) Summary
normalize-packages.mjs CLI 구조 및 상수 정의
scripts/normalize-packages.mjs
정책 주석을 dist-first 계약 중심으로 교체하고, 패키지별 예외 Map과 dist 경로 상수를 추가한다. --check/--write/--root 옵션 파싱과 private 패키지 건너뜀 로직을 포함한 main() 루프를 구현한다.
normalizePackage / validatePackage 핵심 로직
scripts/normalize-packages.mjs
publishConfig.access public 강제, publishConfig.files 제거, types 배열→단일 문자열 정규화, publishConfig.exports["."] 재구성을 수행하는 normalizePackage와 보조 함수들을 추가한다. validatePackage가 dist 경로 위반, ./src/ 참조, exports 맵 조건 등 다중 규칙을 검증한다.
개별 패키지 manifest 계약 적용
packages/access-drizzle/package.json, packages/auth-drizzle/package.json, packages/cli/package.json, packages/cli/tsup.config.ts, packages/impersonation-core/package.json, packages/llm-core/package.json, packages/llm-metering/package.json, packages/search-core/package.json, packages/search-drizzle/package.json, packages/search-meilisearch/package.json
각 패키지에 type/main/types(./src/index.ts)를 추가하고 publishConfig 아래 dist 기반 엔트리를 설정한다. impersonation-coretypes 배열을 단일 문자열로 수정하고 clitsup에서 dts: true를 활성화한다.
package-entrypoint-smoke 스모크 테스트
scripts/package-entrypoint-smoke.mts
framework-contextpublishConfig를 제거한 manifest를 임시 node_modules에 기록하고 dist를 symlink한 뒤 CJS/ESM/TypeScript 소비자 파일을 생성해 런타임 실행과 tsc(NodeNext, noEmit) 컴파일을 검증한다.
normalize-packages.mjs 통합 테스트
scripts/tests/normalize-packages.spec.ts
--check 모드의 드리프트 감지 및 파일 미수정, --write 모드의 계약 정규화 결과, 비-라이브러리 패키지 예외 처리를 검증하는 3개 통합 테스트 시나리오와 헬퍼를 추가한다.
CI 게이트, 루트 스크립트, 문서, changeset
.github/workflows/ci.yml, .github/workflows/release.yml, package.json, docs/release/package-entrypoint-contract.md, .changeset/package-entrypoint-contracts.md
CI/Release 워크플로우에 manifest contract check → build → entrypoint smoke 순서의 검증 단계를 추가하고, 루트 check 스크립트에 package-manifests:check를 선행 추가하며 smoke/check/write 스크립트를 신규 등록한다. 배포 계약 문서와 changeset 메타데이터를 함께 추가한다.

Sequence Diagram(s)

sequenceDiagram
  rect rgba(173, 216, 230, 0.5)
    Note over CI,normalize-packages.mjs: CI Validate / Release 파이프라인
  end
  participant CI as CI/Release Workflow
  participant normalize-packages.mjs as normalize-packages.mjs
  participant smoke as package-entrypoint-smoke.mts
  participant tsc as tsc (NodeNext)
  participant node as node runtime

  CI->>normalize-packages.mjs: pnpm package-manifests:check (--check)
  normalize-packages.mjs-->>CI: 위반 목록 출력 또는 OK
  CI->>CI: pnpm build
  CI->>smoke: pnpm package-entrypoints:smoke
  smoke->>smoke: 임시 node_modules 구성 + dist symlink
  smoke->>node: cjs.cjs 실행 (Container/Context 확인)
  smoke->>node: esm.mjs 실행 (Container/Context 확인)
  smoke->>tsc: types.ts 타입 컴파일 (noEmit)
  tsc-->>smoke: 성공 / 실패
  smoke-->>CI: 결과 반환
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 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 모든 #618 요구사항 충족: manifest 표준 정의, normalize-packages.mjs write/check 모드 분리, CI hard fail 통합, 패키지 예외 문서화, CJS/ESM/TypeScript 스모크 테스트 검증
Out of Scope Changes check ✅ Passed 모든 변경사항이 #618 범위 내 entrypoint contract 강제와 직접 관련되며 스코프 이탈 변경이 없습니다.
Title check ✅ Passed PR 제목은 패키지 엔트리포인트 계약 강화 및 검증 게이트 추가라는 주요 변경 사항을 정확하게 반영하고 있습니다.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/618-package-entrypoint-contracts

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.

@kang-heewon
kang-heewon force-pushed the fix/618-package-entrypoint-contracts branch from e54f752 to 4112be8 Compare June 14, 2026 06:42
@kang-heewon kang-heewon changed the title fix: enforce public package entrypoint contracts fix: harden package entrypoint and validation gates Jun 14, 2026
coderabbitai[bot]
coderabbitai Bot previously requested changes Jun 14, 2026

@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: 2

Caution

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

⚠️ Outside diff range comments (1)
scripts/tests/normalize-packages.spec.ts (1)

1-166: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

TS 문자열 리터럴 규칙(싱글 쿼트) 위반이 파일 전반에 있습니다.

Line 1-6 import 구문과 테스트/헬퍼 문자열들 전반을 싱글 쿼트로 통일해 주세요.
As per coding guidelines, 'Use single quotes for string literals'.

🤖 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 `@scripts/tests/normalize-packages.spec.ts` around lines 1 - 166, Replace all
double quotes with single quotes throughout the entire file to comply with
TypeScript string literal conventions. This includes all import statements
(lines 1-6), all test description strings and expect assertion messages in the
describe and it blocks, object property values, file paths in function calls
like writePackage and runScript, and all other string literals throughout the
test file and helper functions.

Source: Coding guidelines

🤖 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/normalize-packages.mjs`:
- Around line 345-347: The hardcoded POSIX path comparison in the condition
checking relativePath === "packages/impersonation-core/package.json" fails on
Windows because path.relative() returns backslash separators on that platform,
causing the condition to evaluate to false and skip the validation for the
impersonation-core package. Replace this path-based string comparison with a
package name-based comparison by checking if pkg.name equals
"impersonation-core" instead, which will work consistently across all platforms
regardless of path separator differences.

In `@scripts/package-entrypoint-smoke.mts`:
- Around line 99-110: The spawnSync call starting at line 99 lacks a timeout
setting which can cause the Node.js event loop to block indefinitely if a child
process hangs. Additionally, the error handling block at lines 105-110 only
checks result.status but ignores result.error, which means spawn execution
failures like missing executable or permission errors are not captured. Add a
timeout option (in milliseconds) to the spawnSync options object, and modify the
error handling to check if result.error exists and include it in the thrown
Error message along with the existing stdout and stderr information.

---

Outside diff comments:
In `@scripts/tests/normalize-packages.spec.ts`:
- Around line 1-166: Replace all double quotes with single quotes throughout the
entire file to comply with TypeScript string literal conventions. This includes
all import statements (lines 1-6), all test description strings and expect
assertion messages in the describe and it blocks, object property values, file
paths in function calls like writePackage and runScript, and all other string
literals throughout the test file and helper functions.
🪄 Autofix (Beta)

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: 1b8c6365-a110-4db7-8651-557af28ad849

📥 Commits

Reviewing files that changed from the base of the PR and between 8e3bdb6 and e54f752.

📒 Files selected for processing (18)
  • .changeset/package-entrypoint-contracts.md
  • .github/workflows/ci.yml
  • .github/workflows/release.yml
  • docs/release/package-entrypoint-contract.md
  • package.json
  • packages/access-drizzle/package.json
  • packages/auth-drizzle/package.json
  • packages/cli/package.json
  • packages/cli/tsup.config.ts
  • packages/impersonation-core/package.json
  • packages/llm-core/package.json
  • packages/llm-metering/package.json
  • packages/search-core/package.json
  • packages/search-drizzle/package.json
  • packages/search-meilisearch/package.json
  • scripts/normalize-packages.mjs
  • scripts/package-entrypoint-smoke.mts
  • scripts/tests/normalize-packages.spec.ts

Comment thread scripts/normalize-packages.mjs Outdated
Comment thread scripts/package-entrypoint-smoke.mts
@github-actions

github-actions Bot commented Jun 14, 2026

Copy link
Copy Markdown

📊 Benchmark Results

❌ Some benchmarks failed

Benchmark p75 Threshold Baseline vs Baseline Status
CrocoApp benchmarks 3.1μs - - - ⚠️
EventBusConfig.start (10 handlers) 1.5μs - 9.0μs -83.2%
EventPublisher.publishNow single event 1.7μs - - - ⚠️
DefaultHandlerResolver.resolve × 10 0.1μs - 0.2μs -66.5%
Container.get singleton (cold) 1.1μs - 0.5μs +117.2%
Container.register × 50 components 12.0μs - 8.0μs +50.4%
Container.validate (50 components) 30.1μs - 25.0μs +20.3%
Container.get singleton (warm) 0.4μs - 0.3μs +31.0%
TelemetryRuntime benchmarks 2.0μs - 2.0μs -2.1%

Updated: 2026-06-14T07:18:53.735Z · Commit: 3c1c906

@kang-heewon
kang-heewon force-pushed the fix/618-package-entrypoint-contracts branch from 4112be8 to a38b199 Compare June 14, 2026 06:56
@kang-heewon
kang-heewon dismissed coderabbitai[bot]’s stale review June 14, 2026 06:57

Addressed in a38b199: the path comparison now uses package name, spawnSync has timeout/error reporting, and the normalize package test uses single quotes with formatter hook/check alignment.

@kang-heewon
kang-heewon force-pushed the fix/618-package-entrypoint-contracts branch from a38b199 to 2f92b43 Compare June 14, 2026 07:15
@kang-heewon
kang-heewon merged commit a61dcd4 into trunk Jun 14, 2026
7 of 8 checks passed
@kang-heewon
kang-heewon deleted the fix/618-package-entrypoint-contracts branch June 14, 2026 07: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.

[release] Standardize package entrypoint contracts across all public packages

1 participant