一键导入
config-state-audit
Use when changing revision bumps, ETags, config environment state rows, public config invalidation, or audit logs.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when changing revision bumps, ETags, config environment state rows, public config invalidation, or audit logs.
用 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 | config-state-audit |
| description | Use when changing revision bumps, ETags, config environment state rows, public config invalidation, or audit logs. |
Generated from ai/registry.json. Do not edit manually.
Canonical skill: ../../../ai/skills/config-state-audit.md.
Referenced context:
../../../ai/rules/config-state-audit-rules.md../../../ai/rules/public-config-rules.md../../../ai/architecture/config-state-audit-flow.md../../../ai/architecture/public-config-flow.md../../../ai/examples/good-config-state-audit.mdThis file is compiled from canonical AI knowledge files. Edit canonical files under ai, then run npm run ai:sync.
ai/skills/config-state-audit.mdUse this skill when changing revision bumps, ETags, config environment state rows, public config invalidation, or audit logs.
Keep SDK-visible state changes, public cache metadata, and audit logs consistent and transactional.
ai/rules/config-state-audit-rules.mdai/rules/public-config-rules.mdai/architecture/config-state-audit-flow.mdai/architecture/public-config-flow.mdai/examples/good-config-state-audit.mdbumpConfigEnvironmentState() only for SDK-visible changes.createAuditLog() and toAuditJson() for audit payloads.npm --workspace @capture-flag/api run build after service/helper changes.ai/rules/config-state-audit-rules.mdRules for config environment state, revision bumps, ETags, and audit logs.
config_environment_states as the source of public config revision, ETag, and generatedAt.bumpConfigEnvironmentState() inside the same transaction as the SDK-visible write.createConfigEnvironmentEtag() instead of duplicating string format logic.toAuditJson() when persisting old/new/metadata snapshots.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/config-state-audit-flow.mdConfig environment state connects private writes to public SDK cache behavior.
config + environment public config state.revision, etag, and generatedAt used by the public Config JSON endpoint.bumpConfigEnvironmentState(tx, configId, environmentId) in that transaction.revision, updates generatedAt, reads the new revision, and updates etag through createConfigEnvironmentEtag().audit_logs in the same transaction as the domain write.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-config-state-audit.mdSource: apps/api/src/common/config-state.ts (sha256: 0f307de98712c0bd2e2a790b888d6f710bb9689666da1a257b7a999a788a30f2)
Source: apps/api/src/common/audit-log.ts (sha256: 6ec7b0b9b5fd8eb4073d46719dc01bf60c39be927b6cd3cc693ec20d409d93eb)
Source: apps/api/src/environments/support/environment-config-state.service.ts (sha256: 12113d90ef325a80ac19999d713e6374355ca23af107ecf3a7459c239b3359da)
Why this is canonical:
await tx.configEnvironmentState.updateMany({
where: { configId, environmentId },
data: {
revision: { increment: 1 },
generatedAt: new Date(),
},
});
The helper then reads the new revision and updates the ETag in the same transaction.
await tx.auditLog.create({
data: {
action: input.action,
actorUserId: input.actorUserId ?? null,
metadata: input.metadata ?? {},
organizationId: input.organizationId,
},
});
Audit entries stay tenant-scoped, append-only, and avoid raw credentials.