ワンクリックで
api-public-config-contract
Use when changing public SDK config JSON, ETags, cache behavior, or SDK key lookup.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Use when changing public SDK config JSON, ETags, cache behavior, or SDK key lookup.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Use when adding, changing, extracting, or reusing client components, including Storybook stories and controls.
Use when adding or changing forms in apps/client.
Use when changing GitHub OAuth, session cookies, SessionGuard, logout, or authenticated API request identity.
Use when adding or changing routes in apps/client.
Use when adding or changing client state, React Query data flow, immutable context values, or Zustand stores.
Use when styling apps/client with Tailwind CSS v4.
| name | api-public-config-contract |
| description | Use when changing public SDK config JSON, ETags, cache behavior, or SDK key lookup. |
Generated from ai/registry.json. Do not edit manually.
Canonical skill: ../../../ai/skills/api-public-config-contract.md.
Referenced context:
../../../ai/glossary/config-sdk-terms.md../../../ai/rules/public-config-rules.md../../../ai/architecture/public-config-flow.md../../../ai/examples/good-public-config-service.mdThis file is compiled from canonical AI knowledge files. Edit canonical files under ai, then run npm run ai:sync.
ai/skills/api-public-config-contract.mdUse this skill when changing the public SDK config endpoint, SDK key lookup, ETags, cache behavior, config revisioning, or public flag serialization.
Preserve the SDK-visible Config JSON contract and HTTP cache semantics while keeping evaluation local to SDKs.
ai/glossary/config-sdk-terms.mdai/rules/public-config-rules.mdai/architecture/public-config-flow.mdai/examples/good-public-config-service.mddocs/CONFIG_FORMAT.mdrules.lastUsedAt updates after valid SDK access, including not-modified responses, without making telemetry writes break valid responses.apps/api/test/public-sdk.service.spec.ts or equivalent tests for contract changes.npm --workspace @capture-flag/api run test after public config changes.ai/glossary/config-sdk-terms.mdTerms shared by API, public config, evaluator, SDK, and client UI.
SDK-visible setting controlled by Capture Flag. Supported types are boolean, string, integer, double, json_object, and json_array.
Configured flag value stored in the database and emitted in Config JSON. This is not the same as SDK fallback value.
Value supplied by application code when calling getValue. The SDK returns fallback when config is unavailable, invalid, missing, or type-mismatched.
Ordered targeting rules emitted as rules in public Config JSON. The evaluator checks rules before percentage rollout.
Reusable group of attribute conditions scoped to one config and emitted as segments in public Config JSON.
A rule condition shaped as { "segment": "segment-key" }. It is evaluated locally by checking the referenced segment conditions against the Evaluation Context.
A rule condition shaped as { "prerequisiteFlag": "flag-key", "operator": "equals", "value": true }. It evaluates another flag from the same Config JSON locally before deciding whether the current rule matches.
Targeting features beyond simple attribute equality: prerequisite flags, arrayContains, date comparisons, and SemVer comparisons.
Deterministic distribution of values based on a rollout attribute such as identifier.
Context attribute used for rollout bucketing. Defaults to identifier.
Read-only credential scoped to one config and one environment. Stored as a hash in the API database.
The full SDK credential shown only immediately after creation. It must never be stored, logged, audited, or re-displayed.
Display-safe prefix derived from the raw SDK key and stored for UI identification and audit metadata.
Versioned public JSON downloaded by SDKs. It contains local-evaluation data, not evaluated flag results.
React provider and hook package that receives a JavaScript SDK client and evaluates flags through that client.
Per config + environment state that stores revision, ETag, and generated timestamp for public config caching.
HTTP cache validator used by SDK clients through If-None-Match.
Default SDK mode. The client fetches config only when no cache exists or when the cached entry is older than cacheTtlMs.
SDK mode where the JavaScript client refreshes config in the background on pollIntervalMs.
SDK mode where getValue uses the current cache and the application calls refresh() to fetch new config.
SDK mode where the client uses only existing cache and never performs network requests.
Default in-process SDK cache used by every client instance.
Browser persistent cache enabled explicitly through SDK options. It stores config, ETag, timestamp, cache schema version, and scope fingerprints, never raw SDK keys or raw base URLs.
Duration used by lazy loading to decide whether a cached config should be refreshed.
ETag stored with the cached config and sent on refresh through If-None-Match.
client.close() stops SDK-owned background polling timers.
ai/rules/public-config-rules.mdRules for the SDK-visible public config endpoint and cache contract.
GET /public-api/v1/sdk/:sdkKey/config unless explicitly changing the contract.schemaVersion: 1 until an explicit versioned contract change is made.ETag and Cache-Control on successful public config responses.Cache-Control safe for SDK-key URLs; shared/CDN caching must be an explicit deployment opt-in.If-None-Match, including weak ETags, comma-separated values, and *.304 Not Modified with no body when the client ETag matches.lastUsedAt after valid SDK config access, including not-modified responses, without making telemetry writes break valid config responses.docs/CONFIG_FORMAT.md, SDK parsing, evaluator expectations, and tests in the same change.projectKey, configKey, environment, revision, generatedAt, segments, and flags.conditions and are keyed by segment key.type, defaultValue, rules, percentageAttribute, and percentageOptions.rules without API-side evaluation.revision, ETag, and generatedAt.ai/architecture/public-config-flow.mdThe public config endpoint serves the SDK-visible JSON contract.
GET /public-api/v1/sdk/:sdkKey/config
The path contains the raw SDK key. The API hashes it for lookup.
The private client preview endpoint reuses the same serialization path for a selected config + environment, but it is session-authenticated, checks project access, does not require a raw SDK key, and does not update SDK key lastUsedAt.
config + environment.If-None-Match against current ETag.304 Not Modified when matched.lastUsedAt after valid access.SDK key, config state, and flag values are read in a transaction so the response body matches the revision and ETag.
The response body contains:
schemaVersionprojectKeyconfigKeyenvironmentrevisiongeneratedAtsegmentsflagsFlag values are local-evaluation data, not evaluated results.
Segments contain reusable local-evaluation conditions. Segment membership is not evaluated by the API.
Advanced targeting data, including prerequisite flag conditions, is serialized inside flag rules. The public API never evaluates prerequisites or receives Evaluation Context.
ai/examples/good-public-config-service.mdSource: apps/api/src/public-sdk/public-sdk.service.ts (sha256: 85e49bab9d48419a9c4333b902d45cd724ae62a4b946eea88831bc3a4d42007c)
Why this is canonical:
Canonical public config pattern from apps/api/src/public-sdk/public-sdk.service.ts.
const transactionResult = await this.prisma.$transaction(
async (tx) => {
const sdkKey = await this.sdkKeyAuth.findActiveSdkKey(tx, rawSdkKey);
const state = await tx.configEnvironmentState.findUnique({
where: {
configId_environmentId: {
configId: sdkKey.configId,
environmentId: sdkKey.environmentId,
},
},
});
},
{ isolationLevel: Prisma.TransactionIsolationLevel.RepeatableRead },
);
The public endpoint authenticates by hashed SDK key and reads config state in the same transaction as flag values.
if (this.cache.matchesIfNoneMatch(ifNoneMatch, state.etag)) {
return {
result: {
etag: state.etag,
cacheControl,
notModified: true,
},
sdkKeyId: sdkKey.id,
};
}
Not-modified responses still count as valid SDK config access for lastUsedAt.
const cacheControl = this.cache.cacheControlHeader();
await this.sdkKeyUsage.recordUse(transactionResult.sdkKeyId);
The public endpoint defaults away from shared caching because the raw SDK key is in the URL path, and usage telemetry is best-effort after a valid config read.