Found by the PR #18 three-agent review (engine reviewer). Convergence risk at the CT-server-behavior boundary.
What happens
A no-op plan requires deepEqual(desired.dynamic, actual.dynamic); normalizeRuleset strips only the two timestamp keys and normalizes the query subtree. The other RuleSet-level fields — description, shorty, importance, personIdFieldName, process — must round-trip byte-for-byte. Fixtures show auto-generated-looking values (e.g. "Automatische Mitgliedschaft für Gruppe #683"); if CT overwrites or normalizes any of these on PUT (plausible for description/shorty, which reference a group id the user can't know before create), an affected dynamic group updates on every apply forever.
The existing live round-trip test writes back CT's own GET output, so it is drift-free by construction and cannot catch a user-authored ruleset diverging from what CT stores.
Fix sketch
Pin CT's write-back behavior with a live-gated test that PUTs a user-authored ruleset (custom description/shorty) and asserts the subsequent GET matches. If CT recomputes fields, extend the normalizer to drop/canonicalize them (like the timestamps) so plans converge.
Acceptance
Found by the PR #18 three-agent review (engine reviewer). Convergence risk at the CT-server-behavior boundary.
What happens
A no-op plan requires
deepEqual(desired.dynamic, actual.dynamic);normalizeRulesetstrips only the two timestamp keys and normalizes thequerysubtree. The other RuleSet-level fields —description,shorty,importance,personIdFieldName,process— must round-trip byte-for-byte. Fixtures show auto-generated-looking values (e.g."Automatische Mitgliedschaft für Gruppe #683"); if CT overwrites or normalizes any of these on PUT (plausible fordescription/shorty, which reference a group id the user can't know before create), an affected dynamic group updates on every apply forever.The existing live round-trip test writes back CT's own GET output, so it is drift-free by construction and cannot catch a user-authored ruleset diverging from what CT stores.
Fix sketch
Pin CT's write-back behavior with a live-gated test that PUTs a user-authored ruleset (custom description/shorty) and asserts the subsequent GET matches. If CT recomputes fields, extend the normalizer to drop/canonicalize them (like the timestamps) so plans converge.
Acceptance