chore(config) rm Feature::CodexGitCommit (#22412)

## Summary
Removes the unused Feature::CodexGitCommit

## Testing
- [x] tests pass
This commit is contained in:
Dylan Hurd
2026-05-13 12:33:36 -07:00
committed by GitHub
Unverified
parent a98b57d065
commit d18a7c982e
14 changed files with 18 additions and 224 deletions
-11
View File
@@ -1902,7 +1902,6 @@ dependencies = [
"codex-feedback",
"codex-file-search",
"codex-file-watcher",
"codex-git-attribution",
"codex-git-utils",
"codex-guardian",
"codex-hooks",
@@ -2912,16 +2911,6 @@ dependencies = [
"tracing",
]
[[package]]
name = "codex-git-attribution"
version = "0.0.0"
dependencies = [
"codex-core",
"codex-extension-api",
"codex-features",
"pretty_assertions",
]
[[package]]
name = "codex-git-utils"
version = "0.0.0"
-2
View File
@@ -46,7 +46,6 @@ members = [
"execpolicy-legacy",
"ext/extension-api",
"ext/guardian",
"ext/git-attribution",
"ext/memories",
"external-agent-migration",
"external-agent-sessions",
@@ -164,7 +163,6 @@ codex-exec-server = { path = "exec-server" }
codex-execpolicy = { path = "execpolicy" }
codex-extension-api = { path = "ext/extension-api" }
codex-guardian = { path = "ext/guardian" }
codex-git-attribution = { path = "ext/git-attribution" }
codex-external-agent-migration = { path = "external-agent-migration" }
codex-external-agent-sessions = { path = "external-agent-sessions" }
codex-experimental-api-macros = { path = "codex-experimental-api-macros" }
-1
View File
@@ -42,7 +42,6 @@ codex-external-agent-migration = { workspace = true }
codex-external-agent-sessions = { workspace = true }
codex-features = { workspace = true }
codex-guardian = { workspace = true }
codex-git-attribution = { workspace = true }
codex-git-utils = { workspace = true }
codex-file-watcher = { workspace = true }
codex-hooks = { workspace = true }
-1
View File
@@ -17,7 +17,6 @@ where
S: AgentSpawner<StartThreadOptions, Spawned = NewThread, Error = CodexErr> + 'static,
{
let mut builder = ExtensionRegistryBuilder::<Config>::new();
codex_git_attribution::install(&mut builder);
codex_guardian::install(&mut builder, guardian_agent_spawner);
Arc::new(builder.build())
}
-8
View File
@@ -177,14 +177,6 @@ pub struct ConfigToml {
/// Compact prompt used for history compaction.
pub compact_prompt: Option<String>,
/// Optional commit attribution text for commit message co-author trailers.
/// This top-level setting only takes effect when `[features].codex_git_commit`
/// is enabled.
///
/// When enabled and unset, Codex uses `Codex <noreply@openai.com>`.
/// Set to an empty string to disable automatic commit attribution.
pub commit_attribution: Option<String>,
/// When set, restricts ChatGPT login to a specific workspace identifier.
#[serde(default)]
pub forced_chatgpt_workspace_id: Option<String>,
-4
View File
@@ -4026,10 +4026,6 @@
"default": null,
"description": "Preferred backend for storing CLI auth credentials. file (default): Use a file in the Codex home directory. keyring: Use an OS-specific keyring service. auto: Use the keyring if available, otherwise use a file."
},
"commit_attribution": {
"description": "Optional commit attribution text for commit message co-author trailers. This top-level setting only takes effect when `[features].codex_git_commit` is enabled.\n\nWhen enabled and unset, Codex uses `Codex <noreply@openai.com>`. Set to an empty string to disable automatic commit attribution.",
"type": "string"
},
"compact_prompt": {
"description": "Compact prompt used for history compaction.",
"type": "string"
-4
View File
@@ -7357,7 +7357,6 @@ async fn test_precedence_fixture_with_o3_profile() -> std::io::Result<()> {
include_skill_instructions: true,
include_environment_context: true,
compact_prompt: None,
commit_attribution: None,
forced_chatgpt_workspace_id: None,
forced_login_method: None,
include_apply_patch_tool: true,
@@ -7805,7 +7804,6 @@ async fn test_precedence_fixture_with_gpt3_profile() -> std::io::Result<()> {
include_skill_instructions: true,
include_environment_context: true,
compact_prompt: None,
commit_attribution: None,
forced_chatgpt_workspace_id: None,
forced_login_method: None,
include_apply_patch_tool: true,
@@ -7967,7 +7965,6 @@ async fn test_precedence_fixture_with_zdr_profile() -> std::io::Result<()> {
include_skill_instructions: true,
include_environment_context: true,
compact_prompt: None,
commit_attribution: None,
forced_chatgpt_workspace_id: None,
forced_login_method: None,
include_apply_patch_tool: true,
@@ -8114,7 +8111,6 @@ async fn test_precedence_fixture_with_gpt5_profile() -> std::io::Result<()> {
include_skill_instructions: true,
include_environment_context: true,
compact_prompt: None,
commit_attribution: None,
forced_chatgpt_workspace_id: None,
forced_login_method: None,
include_apply_patch_tool: true,
-12
View File
@@ -478,15 +478,6 @@ pub struct Config {
/// Compact prompt override.
pub compact_prompt: Option<String>,
/// Optional commit attribution text for commit message co-author trailers.
/// This top-level setting only takes effect when `[features].codex_git_commit`
/// is enabled.
///
/// - `None`: use default attribution (`Codex <noreply@openai.com>`)
/// - `Some("")` or whitespace-only: disable commit attribution
/// - `Some("...")`: use the provided attribution text verbatim
pub commit_attribution: Option<String>,
/// Optional external notifier command. When set, Codex will spawn this
/// program after each completed *turn* (i.e. when the agent finishes
/// processing a user submission). The value must be the full command
@@ -2809,8 +2800,6 @@ impl Config {
}
});
let commit_attribution = cfg.commit_attribution;
// Load base instructions override from a file if specified. If the
// path is relative, resolve it against the effective cwd so the
// behaviour matches other path-like config values.
@@ -3052,7 +3041,6 @@ impl Config {
personality,
developer_instructions,
compact_prompt,
commit_attribution,
include_permissions_instructions,
include_apps_instructions,
include_collaboration_mode_instructions,
+16 -16
View File
@@ -6493,10 +6493,10 @@ async fn make_multi_agent_v2_usage_hint_test_session(
(session, turn_context)
}
struct GitAttributionTestContributor;
struct GitAttributionTestState;
struct PromptExtensionTestContributor;
struct PromptExtensionTestState;
impl codex_extension_api::ContextContributor for GitAttributionTestContributor {
impl codex_extension_api::ContextContributor for PromptExtensionTestContributor {
fn contribute<'a>(
&'a self,
_session_store: &'a codex_extension_api::ExtensionData,
@@ -6506,11 +6506,11 @@ impl codex_extension_api::ContextContributor for GitAttributionTestContributor {
> {
Box::pin(async move {
thread_store
.get::<GitAttributionTestState>()
.get::<PromptExtensionTestState>()
.is_some()
.then(|| {
codex_extension_api::PromptFragment::developer_policy(
"git attribution extension enabled",
"prompt extension enabled",
)
})
.into_iter()
@@ -6519,21 +6519,21 @@ impl codex_extension_api::ContextContributor for GitAttributionTestContributor {
}
}
fn git_attribution_test_registry()
fn prompt_extension_test_registry()
-> Arc<codex_extension_api::ExtensionRegistry<crate::config::Config>> {
let mut builder = codex_extension_api::ExtensionRegistryBuilder::new();
builder.prompt_contributor(Arc::new(GitAttributionTestContributor));
builder.prompt_contributor(Arc::new(PromptExtensionTestContributor));
Arc::new(builder.build())
}
#[tokio::test]
async fn build_initial_context_includes_git_attribution_from_extensions() {
async fn build_initial_context_includes_prompt_fragments_from_extensions() {
let (mut session, turn_context) = make_session_and_context().await;
session.services.extensions = git_attribution_test_registry();
session.services.extensions = prompt_extension_test_registry();
session
.services
.thread_extension_data
.insert(GitAttributionTestState);
.insert(PromptExtensionTestState);
let initial_context = session.build_initial_context(&turn_context).await;
let developer_messages = developer_message_texts(&initial_context);
@@ -6542,15 +6542,15 @@ async fn build_initial_context_includes_git_attribution_from_extensions() {
developer_messages
.iter()
.flatten()
.any(|text| *text == "git attribution extension enabled"),
"expected git attribution developer text, got {developer_messages:?}"
.any(|text| *text == "prompt extension enabled"),
"expected prompt extension developer text, got {developer_messages:?}"
);
}
#[tokio::test]
async fn build_initial_context_omits_git_attribution_when_feature_is_disabled() {
async fn build_initial_context_omits_prompt_fragments_without_extension_state() {
let (mut session, turn_context) = make_session_and_context().await;
session.services.extensions = git_attribution_test_registry();
session.services.extensions = prompt_extension_test_registry();
let initial_context = session.build_initial_context(&turn_context).await;
let developer_messages = developer_message_texts(&initial_context);
@@ -6559,8 +6559,8 @@ async fn build_initial_context_omits_git_attribution_when_feature_is_disabled()
!developer_messages
.iter()
.flatten()
.any(|text| *text == "git attribution extension enabled"),
"did not expect git attribution developer text, got {developer_messages:?}"
.any(|text| *text == "prompt extension enabled"),
"did not expect prompt extension developer text, got {developer_messages:?}"
);
}
-6
View File
@@ -1,6 +0,0 @@
load("//:defs.bzl", "codex_rust_crate")
codex_rust_crate(
name = "git-attribution",
crate_name = "codex_git_attribution",
)
-21
View File
@@ -1,21 +0,0 @@
[package]
edition.workspace = true
license.workspace = true
name = "codex-git-attribution"
version.workspace = true
[lib]
name = "codex_git_attribution"
path = "src/lib.rs"
doctest = false
[lints]
workspace = true
[dependencies]
codex-core = { workspace = true }
codex-extension-api = { workspace = true }
codex-features = { workspace = true }
[dev-dependencies]
pretty_assertions = { workspace = true }
-134
View File
@@ -1,134 +0,0 @@
use std::sync::Arc;
use codex_core::config::Config;
use codex_extension_api::ContextContributor;
use codex_extension_api::ExtensionData;
use codex_extension_api::ExtensionRegistryBuilder;
use codex_extension_api::PromptFragment;
use codex_extension_api::ThreadLifecycleContributor;
use codex_extension_api::ThreadStartInput;
use codex_features::Feature;
const DEFAULT_ATTRIBUTION_VALUE: &str = "Codex <noreply@openai.com>";
/// Contributes the configured git-attribution instruction.
#[derive(Clone, Copy, Debug, Default)]
pub struct GitAttributionExtension;
impl ContextContributor for GitAttributionExtension {
fn contribute<'a>(
&'a self,
_session_store: &'a ExtensionData,
thread_store: &'a ExtensionData,
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Vec<PromptFragment>> + Send + 'a>> {
Box::pin(async move {
let Some(config_store) = thread_store.get::<GitAttributionConfig>() else {
return Vec::new();
};
if !config_store.enabled {
return Vec::new();
}
build_instruction(config_store.prompt.as_deref())
.map(PromptFragment::developer_policy)
.into_iter()
.collect()
})
}
}
#[derive(Clone, Debug, Default)]
struct GitAttributionConfig {
enabled: bool,
prompt: Option<String>,
}
impl ThreadLifecycleContributor<Config> for GitAttributionExtension {
fn on_thread_start(&self, input: ThreadStartInput<'_, Config>) {
input.thread_store.insert(GitAttributionConfig {
enabled: input.config.features.enabled(Feature::CodexGitCommit),
prompt: input.config.commit_attribution.clone(),
});
}
}
/// Installs the git-attribution contributors into the extension registry.
pub fn install(registry: &mut ExtensionRegistryBuilder<Config>) {
let extension = Arc::new(GitAttributionExtension);
registry.thread_lifecycle_contributor(extension.clone());
registry.prompt_contributor(extension);
}
fn build_commit_message_trailer(config_attribution: Option<&str>) -> Option<String> {
let value = resolve_attribution_value(config_attribution)?;
Some(format!("Co-authored-by: {value}"))
}
fn build_instruction(config_attribution: Option<&str>) -> Option<String> {
let trailer = build_commit_message_trailer(config_attribution)?;
Some(format!(
"When you write or edit a git commit message, ensure the message ends with this trailer exactly once:\n{trailer}\n\nRules:\n- Keep existing trailers and append this trailer at the end if missing.\n- Do not duplicate this trailer if it already exists.\n- Keep one blank line between the commit body and trailer block."
))
}
fn resolve_attribution_value(config_attribution: Option<&str>) -> Option<String> {
match config_attribution {
Some(value) => {
let trimmed = value.trim();
if trimmed.is_empty() {
None
} else {
Some(trimmed.to_string())
}
}
None => Some(DEFAULT_ATTRIBUTION_VALUE.to_string()),
}
}
#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq;
use super::build_commit_message_trailer;
use super::build_instruction;
use super::resolve_attribution_value;
#[test]
fn blank_attribution_disables_trailer_prompt() {
assert_eq!(build_commit_message_trailer(Some("")), None);
assert_eq!(build_instruction(Some(" ")), None);
}
#[test]
fn default_attribution_uses_codex_trailer() {
assert_eq!(
build_commit_message_trailer(/*config_attribution*/ None).as_deref(),
Some("Co-authored-by: Codex <noreply@openai.com>")
);
}
#[test]
fn resolve_value_handles_default_custom_and_blank() {
assert_eq!(
resolve_attribution_value(/*config_attribution*/ None),
Some("Codex <noreply@openai.com>".to_string())
);
assert_eq!(
resolve_attribution_value(Some("MyAgent <me@example.com>")),
Some("MyAgent <me@example.com>".to_string())
);
assert_eq!(
resolve_attribution_value(Some("MyAgent")),
Some("MyAgent".to_string())
);
assert_eq!(resolve_attribution_value(Some(" ")), None);
}
#[test]
fn instruction_mentions_trailer_and_omits_generated_with() {
let instruction =
build_instruction(Some("AgentX <agent@example.com>")).expect("instruction expected");
assert!(instruction.contains("Co-authored-by: AgentX <agent@example.com>"));
assert!(instruction.contains("exactly once"));
assert!(!instruction.contains("Generated-with"));
}
}
+2 -3
View File
@@ -130,7 +130,7 @@ pub enum Feature {
RemoteModels,
/// Experimental shell snapshotting.
ShellSnapshot,
/// Enable git commit attribution guidance via model instructions.
/// Removed legacy git commit attribution guidance flag.
CodexGitCommit,
/// Enable runtime metrics snapshots via a manual reader.
RuntimeMetrics,
@@ -784,11 +784,10 @@ pub const FEATURES: &[FeatureSpec] = &[
stage: Stage::Removed,
default_enabled: false,
},
// Experimental program. Rendered in the `/experimental` menu for users.
FeatureSpec {
id: Feature::CodexGitCommit,
key: "codex_git_commit",
stage: Stage::UnderDevelopment,
stage: Stage::Removed,
default_enabled: false,
},
FeatureSpec {
@@ -196,7 +196,6 @@ fn new_config(model: Option<String>, arg0_paths: Arg0DispatchPaths) -> anyhow::R
include_skill_instructions: false,
include_environment_context: false,
compact_prompt: None,
commit_attribution: None,
notify: None,
tui_notifications: TuiNotificationSettings::default(),
animations: true,