diff --git a/README.md b/README.md
index 6752d1f..7f353b8 100644
--- a/README.md
+++ b/README.md
@@ -167,6 +167,33 @@
과거에는 `dev`/`main` 두 개의 장수 branch를 cherry-pick으로 동기화하는 방식이었으나, 두 branch가 내용상 계속 어긋나는 문제(cherry-pick hell)가 반복되어 폐기했다. staging 배포도 `main` push를 기준으로 트리거된다.
+### 🚩 Feature Flag
+
+미완성/위험도 있는 기능을 브랜치에 오래 묵히지 않고 `main`에 먼저 merge한 뒤, 배포 이후 원하는 시점에 켤 수 있게 하는 최소 구현이다. (`org.runnect.server.config.featureflag`)
+
+```yaml
+# application.yml (environment별로 값이 다를 수 있음)
+feature-flags:
+ flags:
+ new-run-summary: false
+```
+
+```java
+@RequiredArgsConstructor
+public class SomeService {
+ private final FeatureFlags featureFlags;
+
+ public void doSomething() {
+ if (featureFlags.isEnabled("new-run-summary")) {
+ // 새 로직
+ }
+ // 기존 로직
+ }
+}
+```
+
+yml에 키가 없으면 기본값은 비활성(`false`)이다.
+
diff --git a/src/main/java/org/runnect/server/config/featureflag/FeatureFlagProperties.java b/src/main/java/org/runnect/server/config/featureflag/FeatureFlagProperties.java
new file mode 100644
index 0000000..04583a8
--- /dev/null
+++ b/src/main/java/org/runnect/server/config/featureflag/FeatureFlagProperties.java
@@ -0,0 +1,21 @@
+package org.runnect.server.config.featureflag;
+
+import java.util.HashMap;
+import java.util.Map;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * application.yml의 feature-flags.flags.{key}: true/false 값을 그대로 바인딩한다.
+ * yml에 없는 키는 FeatureFlags에서 false(비활성)로 취급한다.
+ */
+@Getter
+@Setter
+@Component
+@ConfigurationProperties(prefix = "feature-flags")
+public class FeatureFlagProperties {
+
+ private Map flags = new HashMap<>();
+}
diff --git a/src/main/java/org/runnect/server/config/featureflag/FeatureFlags.java b/src/main/java/org/runnect/server/config/featureflag/FeatureFlags.java
new file mode 100644
index 0000000..f395186
--- /dev/null
+++ b/src/main/java/org/runnect/server/config/featureflag/FeatureFlags.java
@@ -0,0 +1,20 @@
+package org.runnect.server.config.featureflag;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+/**
+ * 미완성/위험도가 있는 기능을 main에 먼저 merge하고 배포 이후에 켤 수 있게 하는
+ * 트렁크 기반 개발용 최소 기능 플래그. 값은 environment별 application.yml의
+ * feature-flags.flags.{key}로 관리한다 (예: feature-flags.flags.new-run-summary: true).
+ */
+@Component
+@RequiredArgsConstructor
+public class FeatureFlags {
+
+ private final FeatureFlagProperties properties;
+
+ public boolean isEnabled(String key) {
+ return properties.getFlags().getOrDefault(key, false);
+ }
+}
diff --git a/src/test/java/org/runnect/server/config/featureflag/FeatureFlagsTest.java b/src/test/java/org/runnect/server/config/featureflag/FeatureFlagsTest.java
new file mode 100644
index 0000000..8e99ca8
--- /dev/null
+++ b/src/test/java/org/runnect/server/config/featureflag/FeatureFlagsTest.java
@@ -0,0 +1,35 @@
+package org.runnect.server.config.featureflag;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Map;
+import org.junit.jupiter.api.Test;
+
+class FeatureFlagsTest {
+
+ @Test
+ void yml에_true로_설정된_플래그는_활성이다() {
+ FeatureFlagProperties properties = new FeatureFlagProperties();
+ properties.setFlags(Map.of("new-run-summary", true));
+ FeatureFlags featureFlags = new FeatureFlags(properties);
+
+ assertThat(featureFlags.isEnabled("new-run-summary")).isTrue();
+ }
+
+ @Test
+ void yml에_false로_설정된_플래그는_비활성이다() {
+ FeatureFlagProperties properties = new FeatureFlagProperties();
+ properties.setFlags(Map.of("new-run-summary", false));
+ FeatureFlags featureFlags = new FeatureFlags(properties);
+
+ assertThat(featureFlags.isEnabled("new-run-summary")).isFalse();
+ }
+
+ @Test
+ void yml에_정의되지_않은_플래그는_기본값으로_비활성이다() {
+ FeatureFlagProperties properties = new FeatureFlagProperties();
+ FeatureFlags featureFlags = new FeatureFlags(properties);
+
+ assertThat(featureFlags.isEnabled("존재하지-않는-플래그")).isFalse();
+ }
+}