Skip to content

Commit 833506f

Browse files
Use primary source for composed hook requirements
When managed hooks come from a composed requirements field, map the hook source through the first contributing requirements source instead of treating every composite as cloud requirements. This keeps hook source attribution coarse but honest: requirements composition preserves source order by priority, while hook discovery still only carries one source for the merged hooks field rather than exact per-hook provenance.
1 parent 0018edf commit 833506f

1 file changed

Lines changed: 30 additions & 3 deletions

File tree

codex-rs/hooks/src/engine/discovery.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -612,9 +612,15 @@ fn hook_source_for_requirement_source(source: Option<&RequirementSource>) -> Hoo
612612
Some(RequirementSource::LegacyManagedConfigTomlFromMdm) => {
613613
HookSource::LegacyManagedConfigMdm
614614
}
615-
Some(RequirementSource::CloudRequirements)
616-
| Some(RequirementSource::Composite { .. })
617-
| Some(RequirementSource::EnterpriseManaged { .. }) => HookSource::CloudRequirements,
615+
Some(RequirementSource::CloudRequirements) => HookSource::CloudRequirements,
616+
Some(RequirementSource::Composite { sources }) => {
617+
// Requirements hook composition preserves contributing sources in
618+
// priority order, but discovery only carries one source for the
619+
// whole merged hooks field. Use the primary contributor as the best
620+
// available coarse attribution.
621+
hook_source_for_requirement_source(sources.first())
622+
}
623+
Some(RequirementSource::EnterpriseManaged { .. }) => HookSource::CloudRequirements,
618624
Some(RequirementSource::Unknown) | None => HookSource::Unknown,
619625
}
620626
}
@@ -624,6 +630,7 @@ mod tests {
624630
use codex_config::ConfigLayerEntry;
625631
use codex_config::ConfigLayerSource;
626632
use codex_config::HookEventsToml;
633+
use codex_config::RequirementSource;
627634
use codex_protocol::protocol::HookEventName;
628635
use codex_protocol::protocol::HookSource;
629636
use codex_utils_absolute_path::AbsolutePathBuf;
@@ -680,6 +687,26 @@ mod tests {
680687
}
681688
}
682689

690+
#[test]
691+
fn composite_requirement_hook_source_uses_primary_source() {
692+
let source = RequirementSource::Composite {
693+
sources: vec![
694+
RequirementSource::SystemRequirementsToml {
695+
file: test_path_buf("/etc/codex/requirements.toml").abs(),
696+
},
697+
RequirementSource::EnterpriseManaged {
698+
id: "layer-1".to_string(),
699+
name: "Engineering".to_string(),
700+
},
701+
],
702+
};
703+
704+
assert_eq!(
705+
super::hook_source_for_requirement_source(Some(&source)),
706+
HookSource::System
707+
);
708+
}
709+
683710
fn command_group(matcher: Option<&str>) -> MatcherGroup {
684711
MatcherGroup {
685712
matcher: matcher.map(str::to_string),

0 commit comments

Comments
 (0)