add-compat-flag

작성자: cloudflare

workerd에 새로운 호환성 플래그를 추가하기 위한 단계별 가이드로, capnp 스키마, C++ 사용법, 테스트 및 문서 요구 사항을 포함합니다.

npx skills add https://github.com/cloudflare/workerd --skill add-compat-flag

Adding a Compatibility Flag

Compatibility flags control behavioral changes in workerd. They allow breaking changes to be rolled out gradually using compatibility dates. Follow these steps in order.

Step 1: Choose flag names

Every flag needs:

  • Enable flag: Opts in to the new behavior (e.g., text_decoder_replace_surrogates)
  • Disable flag: Opts out after it becomes default (e.g., disable_text_decoder_replace_surrogates). Only needed if the flag will eventually become default for all workers.

Naming conventions:

  • Use snake_case
  • Enable flag describes the new behavior positively
  • Disable flag uses a no_ or disable_ prefix, or describes the old behavior

Step 2: Add to compatibility-date.capnp

Edit src/workerd/io/compatibility-date.capnp. Add a new field at the end of the CompatibilityFlags struct.

  myNewBehavior @<NEXT_ORDINAL> :Bool
      $compatEnableFlag("my_new_behavior")
      $compatDisableFlag("no_my_new_behavior")
      $compatEnableDate("2026-03-15");
  # Description of what this flag changes and why.
  # Include context about the old behavior and what the new behavior fixes.

Replace <NEXT_ORDINAL> with the value returned by the next-capnp-ordinal tool.

Key points:

  • The field number must be the next sequential ordinal. Use the next-capnp-ordinal tool to find it: call it with file: "src/workerd/io/compatibility-date.capnp" and struct: "CompatibilityFlags". Do NOT guess or hardcode the number.
  • The field name is camelCase and becomes the C++ getter name (e.g., getMyNewBehavior()).
  • $compatEnableDate is the date after which new workers get this behavior by default. Set this to a future date. If the flag is not yet ready for a default date, omit $compatEnableDate — the flag will only activate when explicitly listed in compatibilityFlags.
  • Add $experimental annotation if the feature is experimental and should require --experimental to use.
  • The comment block is required and serves as internal documentation.

Available annotations:

AnnotationPurpose
$compatEnableFlag("name")Flag name to enable the behavior
$compatDisableFlag("name")Flag name to disable after it's default
$compatEnableDate("YYYY-MM-DD")Date after which behavior is default
$compatEnableAllDatesForce-enable for all dates (rare, breaks back-compat)
$experimentalRequires --experimental flag to use
$neededByFlMust be propagated to Cloudflare's FL proxy layer
$impliedByAfterDate(name = "otherFlag", date = "YYYY-MM-DD")Implied by another flag after a date

Step 3: Use the flag in C++ code

Access the flag via the auto-generated getter:

// In code that has access to jsg::Lock:
if (FeatureFlags::get(js).getMyNewBehavior()) {
  // New behavior
} else {
  // Old behavior
}

The FeatureFlags class is defined in src/workerd/io/features.h. The getter name is derived from the capnp field name with a get prefix and the first letter capitalized.

For JSG API classes, you can also access flags in JSG_RESOURCE_TYPE:

JSG_RESOURCE_TYPE(MyApi, workerd::CompatibilityFlags::Reader flags) {
  if (flags.getMyNewBehavior()) {
    JSG_METHOD(newMethod);
  }
}

Step 4: Add tests

Test both the old and new behavior. The test variant system helps:

  • test-name@ runs with the oldest compat date (2000-01-01) — tests old behavior
  • test-name@all-compat-flags runs with the newest compat date (2999-12-31) — tests new behavior

In your .wd-test file, you can explicitly set the flag:

const unitTests :Workerd.Config = (
  services = [(
    name = "my-test",
    worker = (
      modules = [(name = "worker", esModule = embed "my-test.js")],
      compatibilityFlags = ["my_new_behavior"],
    ),
  )],
);

For tests, the compatibilityDate field should not be included.

Write test cases that verify both behaviors. Consider edge cases where the flag changes observable behavior.

Step 5: Document the flag

This is required before the enable date.

  1. Create a PR in the cloudflare-docs repository.
  2. Add a markdown file under src/content/compatibility-flags/ describing:
    • What the flag does
    • When it becomes default
    • How to opt in or opt out
    • Migration guidance if applicable

See docs/api-updates.md for more details on the documentation process.

Step 6: Build and verify

# Build to verify the capnp schema compiles
just build

# Run the specific test
just stream-test //src/workerd/api/tests:my-test@

# Run with all compat flags to test the new behavior
just stream-test //src/workerd/api/tests:my-test@all-compat-flags

# Run the compatibility-date test to verify flag registration
just stream-test //src/workerd/io:compatibility-date-test@

Checklist

  • Flag added to compatibility-date.capnp with correct sequential field number
  • Enable and disable flag names follow naming conventions
  • Comment block describes old behavior, new behavior, and rationale
  • Enable date is set (or intentionally omitted for experimental/unreleased flags)
  • C++ code uses FeatureFlags::get(js).getMyNewBehavior() to branch on the flag
  • Tests cover both old and new behavior
  • Documentation PR created in cloudflare-docs (required before enable date)
  • compatibility-date-test passes

cloudflare의 다른 스킬

workerd-api-review
cloudflare
workerd 코드 리뷰를 위한 성능 최적화, API 설계 및 호환성, 보안 취약점, 표준 사양 준수. tcmalloc 인식…
official
workerd-safety-review
cloudflare
메모리 안전성, 스레드 안전성, 동시성, 그리고 workerd 코드 리뷰를 위한 중요 탐지 패턴. V8/KJ 경계 위험 요소, 수명 관리 등을 다룹니다.
official
module-registry
cloudflare
workerd에서 모듈 레지스트리를 작업할 때 로드 — 모듈 해석, 컴파일, 평가, 등록을 읽기, 수정, 디버깅, 검토하는 경우…
official
reproduce
cloudflare
cloudflare/agents GitHub 이슈를 재현하기 위해 최소한의 Agents/Worker 프로젝트를 스캐폴딩하고 임시 Cloudflare 계정에 배포한 후 보고합니다…
official
local-explorer
cloudflare
로컬 탐색기 또는 로컬 API에 제품/리소스를 추가하는 방법. 새로운 로컬 API나 UI 라우트를 구현할 때 사용합니다.
official
commit-categories
cloudflare
커밋을 체인지로그와 "새로운 기능" 요약으로 분류하는 규칙입니다. 체인지로그 또는 whats-new 명령에서 커밋을 분류하기 전에 반드시 로드되어야 합니다. 제공하는 기능:
official
architecture
cloudflare
코드베이스를 처음 탐색할 때, 새 클라이언트 메서드를 추가할 때, 새 컨테이너 핸들러/서비스를 추가할 때, 또는 요청 흐름을 이해할 때 사용합니다.
official
changesets
cloudflare
변경셋을 생성하거나, 릴리즈를 준비하거나, 버전을 올릴 때 사용합니다. 참조할 패키지, 사용자 대상 변경셋 설명 작성 방법 등을 다룹니다.
official