feat(core): implement lifecycle tracking issues for features

- Add GitHub issue template for tracking feature maturity (Alpha/Beta/GA).
- Add issueUrl field to FeatureSpec metadata.
- Update /features UI to display tracking issue links.
- Update documentation with requirement for lifecycle trackers.
This commit is contained in:
Jerop Kipruto
2026-02-18 12:29:02 -05:00
parent f1bf34ceee
commit 4663dff8e2
5 changed files with 138 additions and 10 deletions

View File

@@ -0,0 +1,67 @@
name: 'Feature Lifecycle Tracker'
description: 'Track a feature through Alpha, Beta, and GA stages'
labels:
- 'lifecycle/alpha'
- 'status/need-triage'
body:
- type: 'markdown'
attributes:
value: |-
## 🚀 Feature Overview
Provide a concise description of what this feature does and why it is being introduced.
- type: 'textarea'
id: 'spec'
attributes:
label: 'Feature Specification'
description: 'Link to design docs, RFCs, or PRs.'
validations:
required: true
- type: 'markdown'
attributes:
value: |-
## 🗺️ Progression Roadmap
*Maintainers: Update this table and the checkboxes below as the feature matures.*
| Stage | Targeted Version | Actual Version | Date |
| :--- | :--- | :--- | :--- |
| **Alpha** | 0.x.x | | |
| **Beta** | 0.x.x | | |
| **GA** | 0.x.x | | |
- type: 'checkboxes'
id: 'alpha-checklist'
attributes:
label: 'Alpha Requirements (Disabled by Default)'
options:
- label: 'Feature gated by Alpha flag in `packages/core/src/config/features.ts`'
- label: 'Initial implementation merged'
- label: 'Basic unit and integration tests'
- type: 'checkboxes'
id: 'beta-checklist'
attributes:
label: 'Beta Requirements (Enabled by Default)'
options:
- label: 'Feature stable (no major architectural changes) for >= 2 minor versions'
- label: 'Comprehensive documentation in `docs/`'
- label: 'Telemetry/metrics implemented and verified'
- label: 'Promotion PR merged (stage moved to Beta)'
- type: 'checkboxes'
id: 'ga-checklist'
attributes:
label: 'GA Requirements (Locked to Enabled)'
options:
- label: 'Stable for >= 4 minor versions since Beta'
- label: 'No high-priority regressions reported'
- label: 'Performance audit complete'
- label: 'Migration plan (if applicable) documented'
- label: 'PR merged (feature gate removed, code integrated into core)'
- type: 'textarea'
id: 'feedback'
attributes:
label: 'Key Feedback & Bug Links'
description: 'List major bug reports or user feedback threads here.'

View File

@@ -49,7 +49,23 @@ The stability of each feature is visually indicated in the
[`/settings` UI](/docs/cli/settings.md) with colored badges. **GA** features are
considerd stable and look identical to standard settings.
### Precedence and Reconciliation
## Lifecycle tracking issues
Every feature managed under this system must have a corresponding **Lifecycle
Tracking Issue** on GitHub. These issues act as a living roadmap and a public
feedback loop for the feature's progression through Alpha, Beta, and GA stages.
You can find the link to a feature's tracking issue in the following ways:
1. **`/features` Command:** The tracker URL is displayed alongside the metadata
for each feature.
2. **`FeatureDefinitions`:** The `issueUrl` is defined in
`packages/core/src/config/features.ts`.
Maintainers use these issues to document promotion criteria, link related bug
reports, and collect user feedback before moving a feature to the next stage.
### Precedence and reconciliation
When determining if a feature is enabled, the system follows this order of
precedence (highest priority first):
@@ -92,11 +108,14 @@ For more details on persistent configuration, see the [Configuration guide].
Maintaining a feature involves promoting it through stages or eventually
deprecating and removing it.
### Adding a Feature
### Adding a feature
To add a new feature under lifecycle management:
1. **Define the Feature**: Add a new entry to [`FeatureDefinitions`] in
1. **Create a Tracker Issue:** Use the **Feature Lifecycle Tracker** template
on GitHub to create a new issue. This issue will track the feature from
Alpha through GA.
2. **Define the Feature:** Add a new entry to [`FeatureDefinitions`] in
[`features.ts`].
```typescript
@@ -108,6 +127,7 @@ To add a new feature under lifecycle management:
preRelease: FeatureStage.Alpha,
since: '0.31.0',
description: 'Description of my new feature.',
issueUrl: 'https://github.com/google-gemini/gemini-cli/issues/123',
},
],
};
@@ -116,7 +136,7 @@ To add a new feature under lifecycle management:
_Note: The `default` field is optional. If omitted, it defaults to `false`
for Alpha/Deprecated and `true` for Beta/GA._
2. **Expose in Settings**: Add the feature to the `features` object in
3. **Expose in Settings**: Add the feature to the `features` object in
[`settingsSchema.ts`]. This ensures it appears in the `/settings` UI and is
validated.
```typescript
@@ -135,7 +155,7 @@ To add a new feature under lifecycle management:
},
},
```
3. **Use the Feature**: In your code, check if the feature is enabled using the
4. **Use the Feature**: In your code, check if the feature is enabled using the
`Config` object.
```typescript
if (this.config.isFeatureEnabled('myNewFeature')) {
@@ -143,18 +163,21 @@ To add a new feature under lifecycle management:
}
```
### Promoting a Feature
### Promoting a feature
When a feature is ready for the next stage:
1. **Update [`features.ts`]**: Add a new `FeatureSpec` to the feature's array.
1. **Update the Tracker:** Review the requirements in the lifecycle tracker
issue. Once met, update the roadmap table in the issue description and post
a comment announcing the promotion.
2. **Update [`features.ts`]**: Add a new `FeatureSpec` to the feature's array.
- **To BETA**: Set `preRelease: FeatureStage.Beta` (Defaults to `true`).
- **To GA**: Set `preRelease: FeatureStage.GA` (Defaults to `true` and
locked).
- Update the `since` version.
2. **Update [`settingsSchema.ts`]**: Update the `label` and `description` if
3. **Update [`settingsSchema.ts`]**: Update the `label` and `description` if
necessary.
3. **GA Cleanup**: Once a feature is GA and no longer optional, remove the
4. **GA Cleanup**: Once a feature is GA and no longer optional, remove the
feature gate check from the code and make it a core part of the logic.
### Deprecating a Feature

View File

@@ -130,12 +130,22 @@ export const FeaturesList: React.FC<FeaturesListProps> = ({ features }) => {
</Box>
</Box>
{feature.description && (
<Box marginLeft={2} marginBottom={1}>
<Box marginLeft={2}>
<Text dimColor color={theme.text.primary}>
{feature.description}
</Text>
</Box>
)}
{feature.issueUrl && (
<Box marginLeft={2} marginBottom={1}>
<Text color={theme.text.accent}>
Tracker: <Text dimColor>{feature.issueUrl}</Text>
</Text>
</Box>
)}
{!feature.issueUrl && feature.description && (
<Box marginBottom={1} />
)}
</Box>
))}
</Box>

View File

@@ -131,6 +131,7 @@ describe('FeatureGate', () => {
since: '0.1.0',
until: undefined,
description: 'Feature 1',
issueUrl: undefined,
});
expect(feat2).toEqual({
key: 'feat2',
@@ -139,6 +140,27 @@ describe('FeatureGate', () => {
since: '0.2.0',
until: '0.3.0',
description: 'Feature 2',
issueUrl: undefined,
});
});
it('should include issueUrl in feature info', () => {
const gate = DefaultFeatureGate.deepCopy();
gate.add({
featWithUrl: [
{
preRelease: FeatureStage.Alpha,
issueUrl: 'https://github.com/google/gemini-cli/issues/1',
},
],
});
const info = gate.getFeatureInfo();
const feat = info.find((f) => f.key === 'featWithUrl');
expect(feat).toMatchObject({
key: 'featWithUrl',
issueUrl: 'https://github.com/google/gemini-cli/issues/1',
});
});

View File

@@ -65,6 +65,10 @@ export interface FeatureSpec {
* Description of the feature.
*/
description?: string;
/**
* Link to the Lifecycle Tracking Issue on GitHub.
*/
issueUrl?: string;
}
/**
@@ -77,6 +81,7 @@ export interface FeatureInfo {
since?: string;
until?: string;
description?: string;
issueUrl?: string;
}
/**
@@ -216,6 +221,7 @@ class FeatureGateImpl implements MutableFeatureGate {
since: latestSpec.since,
until: latestSpec.until,
description: latestSpec.description,
issueUrl: latestSpec.issueUrl,
};
})
.sort((a, b) => a.key.localeCompare(b.key));