|
187 | 187 | ] |
188 | 188 | } |
189 | 189 | ] |
| 190 | + }, |
| 191 | + { |
| 192 | + "id": "a2a-cancel-canonical-state-guard", |
| 193 | + "title": "A2A cancel canonical state guard", |
| 194 | + "owner": "a2a", |
| 195 | + "bugClass": "canceled tasks overwritten by later stores when status aliases are not canonicalized", |
| 196 | + "why": "store_a2a_task_unless_canceled and a2a_canceled_task must canonicalize the status state before comparing so aliases like CANCELLED or STATE_CANCELED are respected and a canceled row is not overwritten.", |
| 197 | + "evidence": [ |
| 198 | + { |
| 199 | + "path": "packages/control-plane-rs/src/a2a/tasks.rs", |
| 200 | + "contains": [ |
| 201 | + "fn a2a_task_is_canceled", |
| 202 | + "canonical_a2a_task_state(state) == \"TASK_STATE_CANCELED\"", |
| 203 | + "a2a_task_is_canceled(existing)" |
| 204 | + ] |
| 205 | + }, |
| 206 | + { |
| 207 | + "path": "packages/control-plane-rs/src/tests.rs", |
| 208 | + "contains": [ |
| 209 | + "a2a_task_store_preserves_canceled_task_across_canonical_state_aliases" |
| 210 | + ] |
| 211 | + } |
| 212 | + ] |
| 213 | + }, |
| 214 | + { |
| 215 | + "id": "a2a-compound-secret-redaction", |
| 216 | + "title": "A2A compound secret redaction", |
| 217 | + "owner": "a2a", |
| 218 | + "bugClass": "compound credential metadata keys not redacted by exact-match-only secret detection", |
| 219 | + "why": "a2a_ledger_metadata_key_is_secret must match suffix forms (webhookSecret, oauthToken, apiPassword) so compound credential fields are redacted, while preserving nonSecret/nonCredentials/notASecret exceptions and token-metric carve-outs.", |
| 220 | + "evidence": [ |
| 221 | + { |
| 222 | + "path": "packages/control-plane-rs/src/a2a/ledger.rs", |
| 223 | + "contains": [ |
| 224 | + "fn a2a_ledger_metadata_key_has_secret_suffix", |
| 225 | + "SECRET_SUFFIXES", |
| 226 | + "NEGATION_PREFIXES" |
| 227 | + ] |
| 228 | + }, |
| 229 | + { |
| 230 | + "path": "packages/control-plane-rs/src/tests.rs", |
| 231 | + "contains": [ |
| 232 | + "a2a_task_ledger_redacts_compound_secret_metadata_keys" |
| 233 | + ] |
| 234 | + } |
| 235 | + ] |
| 236 | + }, |
| 237 | + { |
| 238 | + "id": "a2a-history-rich-part-refresh", |
| 239 | + "title": "A2A history rich part refresh", |
| 240 | + "owner": "a2a", |
| 241 | + "bugClass": "non-text history parts dropped or stale text preserved during transcript-driven refresh", |
| 242 | + "why": "a2a_merge_history_parts must preserve non-text parts (attachments, data payloads) while replacing all text-bearing parts (plain or decorated) with the refreshed transcript candidate so stale summary text does not survive.", |
| 243 | + "evidence": [ |
| 244 | + { |
| 245 | + "path": "packages/control-plane-rs/src/a2a/ledger.rs", |
| 246 | + "contains": [ |
| 247 | + "fn a2a_merge_history_parts", |
| 248 | + "fn a2a_history_part_has_text", |
| 249 | + "!a2a_history_part_has_text(part)" |
| 250 | + ] |
| 251 | + }, |
| 252 | + { |
| 253 | + "path": "packages/control-plane-rs/src/tests.rs", |
| 254 | + "contains": [ |
| 255 | + "a2a_task_load_preserves_rich_parts_when_history_message_is_refreshed" |
| 256 | + ] |
| 257 | + } |
| 258 | + ] |
| 259 | + }, |
| 260 | + { |
| 261 | + "id": "learner-transient-quarantine-parity", |
| 262 | + "title": "Learner transient quarantine parity", |
| 263 | + "owner": "learner", |
| 264 | + "bugClass": "transient setup failures depressing durable routing confidence across record, load, and trim paths", |
| 265 | + "why": "record_outcome, load, and trim must all exclude transient failures from pattern updates so get_label_success_rate and get_confidence_adjustment stay consistent with get_recommendations. Ambiguous transient phrases must be gated behind environment context.", |
| 266 | + "evidence": [ |
| 267 | + { |
| 268 | + "path": "packages/ambient-agent-rs/src/learner.rs", |
| 269 | + "contains": [ |
| 270 | + "fn is_transient_failure_reason", |
| 271 | + "has_transient_environment_context", |
| 272 | + "fn rebuild_patterns", |
| 273 | + "outcome_is_transient_failure" |
| 274 | + ] |
| 275 | + }, |
| 276 | + { |
| 277 | + "path": "packages/ambient-agent-rs/src/learner.rs", |
| 278 | + "contains": [ |
| 279 | + "test_transient_classifier_requires_environment_context_for_product_terms", |
| 280 | + "test_recommendations_use_consistent_non_transient_stats_after_trim" |
| 281 | + ] |
| 282 | + } |
| 283 | + ] |
| 284 | + }, |
| 285 | + { |
| 286 | + "id": "learner-promote-repair-consistency", |
| 287 | + "title": "Learner promote repair consistency", |
| 288 | + "owner": "learner", |
| 289 | + "bugClass": "same pattern qualifying for both promote and repair or using inconsistent stats", |
| 290 | + "why": "get_recommendations must use pattern_non_transient_stats for both promote and repair decisions and exclude promoted patterns from repair candidates so a single pattern cannot appear in both lists.", |
| 291 | + "evidence": [ |
| 292 | + { |
| 293 | + "path": "packages/ambient-agent-rs/src/learner.rs", |
| 294 | + "contains": [ |
| 295 | + "fn pattern_non_transient_stats", |
| 296 | + "promoted.contains", |
| 297 | + "problematic_pattern_stats" |
| 298 | + ] |
| 299 | + }, |
| 300 | + { |
| 301 | + "path": "packages/ambient-agent-rs/src/learner.rs", |
| 302 | + "contains": [ |
| 303 | + "test_recommendations_do_not_promote_and_repair_the_same_pattern" |
| 304 | + ] |
| 305 | + } |
| 306 | + ] |
190 | 307 | } |
191 | 308 | ] |
192 | 309 | } |
0 commit comments