@@ -14,15 +14,15 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
1414const FIXTURES = path . resolve ( __dirname , "../../test/fixtures/rules" ) ;
1515
1616describe ( "rule-loader: valid fixtures" , ( ) => {
17- it ( "loads smoke -red-tick.yml with merged defaults + escalation + guards" , async ( ) => {
17+ it ( "loads agent -red-tick.yml with merged defaults + escalation + guards" , async ( ) => {
1818 const loader = createRuleLoader ( {
1919 dir : path . join ( FIXTURES , "valid" ) ,
2020 logger,
2121 } ) ;
2222 const rules = await loader . load ( ) ;
2323 expect ( rules ) . toHaveLength ( 1 ) ;
2424 const r = rules [ 0 ] ! ;
25- expect ( r . id ) . toBe ( "smoke -red-tick" ) ;
25+ expect ( r . id ) . toBe ( "agent -red-tick" ) ;
2626 expect ( r . severity ) . toBe ( "warn" ) ;
2727 expect ( r . stringTriggers ) . toEqual ( [
2828 "green_to_red" ,
@@ -579,8 +579,8 @@ describe("rule-loader: invalid fixtures (skipped, not fatal)", () => {
579579 path . join ( tmp , "_defaults.yml" ) ,
580580 ) ;
581581 await fs . copyFile (
582- path . join ( FIXTURES , "valid" , "smoke -red-tick.yml" ) ,
583- path . join ( tmp , "smoke -red-tick.yml" ) ,
582+ path . join ( FIXTURES , "valid" , "agent -red-tick.yml" ) ,
583+ path . join ( tmp , "agent -red-tick.yml" ) ,
584584 ) ;
585585 // Drop a broken file alongside.
586586 await fs . copyFile (
@@ -590,7 +590,7 @@ describe("rule-loader: invalid fixtures (skipped, not fatal)", () => {
590590 const loader = createRuleLoader ( { dir : tmp , logger } ) ;
591591 const { rules, errors } = await loader . loadWithErrors ( ) ;
592592 expect ( rules ) . toHaveLength ( 1 ) ;
593- expect ( rules [ 0 ] ! . id ) . toBe ( "smoke -red-tick" ) ;
593+ expect ( rules [ 0 ] ! . id ) . toBe ( "agent -red-tick" ) ;
594594 expect ( errors ) . toHaveLength ( 1 ) ;
595595 expect ( errors [ 0 ] ! . file ) . toBe ( "missing-id.yml" ) ;
596596 } ) ;
@@ -612,16 +612,16 @@ describe("rule-loader: reload error propagation", () => {
612612 path . join ( tmp , "_defaults.yml" ) ,
613613 ) ;
614614 await fs . copyFile (
615- path . join ( FIXTURES , "valid" , "smoke -red-tick.yml" ) ,
616- path . join ( tmp , "smoke -red-tick.yml" ) ,
615+ path . join ( FIXTURES , "valid" , "agent -red-tick.yml" ) ,
616+ path . join ( tmp , "agent -red-tick.yml" ) ,
617617 ) ;
618618 await fs . copyFile (
619619 path . join ( FIXTURES , "invalid" , "missing-id.yml" ) ,
620620 path . join ( tmp , "missing-id.yml" ) ,
621621 ) ;
622622 const loader = createRuleLoader ( { dir : tmp , logger } ) ;
623623 const { rules, errors } = await loader . loadWithErrors ( ) ;
624- expect ( rules . map ( ( r ) => r . id ) ) . toEqual ( [ "smoke -red-tick" ] ) ;
624+ expect ( rules . map ( ( r ) => r . id ) ) . toEqual ( [ "agent -red-tick" ] ) ;
625625 expect ( errors . map ( ( e ) => e . file ) ) . toEqual ( [ "missing-id.yml" ] ) ;
626626 } ) ;
627627
@@ -1418,108 +1418,6 @@ describe("rule-loader + renderer: full YAML contract coverage", () => {
14181418 } ) ;
14191419 } ) ;
14201420
1421- // ---- smoke-red-tick.yml -------------------------------------------
1422- describe ( "smoke-red-tick" , ( ) => {
1423- it ( "green_to_red branch renders slug, errorDesc and endpoint link" , async ( ) => {
1424- const { rules, errors, renderer } = await loadRealRules ( ) ;
1425- expect (
1426- errors . find ( ( e ) => e . file . startsWith ( "smoke-red-tick" ) ) ,
1427- ) . toBeUndefined ( ) ;
1428- const rule = rules . find ( ( r ) => r . id === "smoke-red-tick" ) ;
1429- expect ( rule ) . toBeDefined ( ) ;
1430- expect ( rule ! . stringTriggers ) . toEqual ( [
1431- "green_to_red" ,
1432- "sustained_red" ,
1433- "red_to_green" ,
1434- ] ) ;
1435- const ctx = makeCtx (
1436- rule ! ,
1437- {
1438- slug : "coagents-starter" ,
1439- errorDesc : "http 503" ,
1440- // A3: driver signal carries `url` (endpoint that was probed)
1441- // instead of a `links` object — the template now renders a single
1442- // endpoint link rather than separate smoke/health pair.
1443- url : "https://svc.example/smoke" ,
1444- failCount : 1 ,
1445- } ,
1446- { trigger : { green_to_red : true , isRedTick : true } } ,
1447- ) ;
1448- const text = (
1449- renderer . render ( { text : rule ! . template ! . text } , ctx ) . payload as {
1450- text : string ;
1451- }
1452- ) . text ;
1453- expect ( text ) . toContain ( "coagents-starter" ) ;
1454- expect ( text ) . toContain ( "down, error: http 503" ) ;
1455- // Triple-brace signal.url (marked slackSafe in LIVENESS_SLACK_SAFE_FIELDS)
1456- // preserves the raw URL inside `<URL|label>` Slack link markup; prior
1457- // double-brace would HTML-escape `/` → `/` and break the link at
1458- // Slack render time.
1459- expect ( text ) . toContain ( "<https://svc.example/smoke|endpoint>" ) ;
1460- } ) ;
1461-
1462- it ( "sustained_red branch renders failCount (attempt: N) and error" , async ( ) => {
1463- const { rules, renderer } = await loadRealRules ( ) ;
1464- const rule = rules . find ( ( r ) => r . id === "smoke-red-tick" ) ! ;
1465- const ctx = makeCtx (
1466- rule ,
1467- {
1468- slug : "mastra-starter" ,
1469- errorDesc : "timeout after 15000ms" ,
1470- // A3: endpoint URL lives under `signal.url` now.
1471- url : "https://m.example/smoke" ,
1472- failCount : 3 ,
1473- } ,
1474- { trigger : { sustained_red : true , isRedTick : true } } ,
1475- ) ;
1476- const text = (
1477- renderer . render ( { text : rule . template ! . text } , ctx ) . payload as {
1478- text : string ;
1479- }
1480- ) . text ;
1481- expect ( text ) . toContain ( "mastra-starter" ) ;
1482- expect ( text ) . toContain ( "attempt: 3" ) ;
1483- expect ( text ) . toContain ( "timeout after 15000ms" ) ;
1484- } ) ;
1485-
1486- it ( "red_to_green branch renders recovery + firstFailureAt" , async ( ) => {
1487- const { rules, renderer } = await loadRealRules ( ) ;
1488- const rule = rules . find ( ( r ) => r . id === "smoke-red-tick" ) ! ;
1489- const ctx = makeCtx (
1490- rule ,
1491- {
1492- slug : "langgraph-starter" ,
1493- firstFailureAt : "2026-04-19T23:00:00Z" ,
1494- } ,
1495- { trigger : { red_to_green : true } } ,
1496- ) ;
1497- const text = (
1498- renderer . render ( { text : rule . template ! . text } , ctx ) . payload as {
1499- text : string ;
1500- }
1501- ) . text ;
1502- expect ( text ) . toContain ( "langgraph-starter" ) ;
1503- expect ( text ) . toContain ( "recovered" ) ;
1504- expect ( text ) . toContain ( "was down since 2026-04-19T23:00:00Z" ) ;
1505- } ) ;
1506-
1507- it ( "fleet rule owns <!channel> escalation (migrated from per-service red-tick)" , async ( ) => {
1508- // Plan Item 4: <!channel> moved off smoke-red-tick onto smoke-red-fleet.
1509- // The per-service rule still fires per-match via its own targets; the
1510- // fleet rule is the single pager for cross-service outages. Per-service
1511- // red-tick template must NOT contain <!channel>; fleet rule template
1512- // MUST. Both invariants asserted together so a future refactor can't
1513- // silently drop one without the other surfacing.
1514- const { rules } = await loadRealRules ( ) ;
1515- const perService = rules . find ( ( r ) => r . id === "smoke-red-tick" ) ! ;
1516- const fleet = rules . find ( ( r ) => r . id === "smoke-red-fleet" ) ! ;
1517- expect ( perService . template ! . text ) . not . toContain ( "<!channel>" ) ;
1518- expect ( fleet . aggregation ) . toBeDefined ( ) ;
1519- expect ( fleet . aggregation ! . template ) . toContain ( "<!channel>" ) ;
1520- } ) ;
1521- } ) ;
1522-
15231421 // ---- deploy-result.yml (remaining branches R20 didn't cover) ------
15241422 describe ( "deploy-result (R20 follow-up branches)" , ( ) => {
15251423 it ( "green_to_red partial branch renders failed/succeeded lists" , async ( ) => {
@@ -1680,8 +1578,8 @@ describe("rule-loader: initial load emits rules.reload.failed on errors (R24 buc
16801578 path . join ( tmp , "_defaults.yml" ) ,
16811579 ) ;
16821580 await fs . copyFile (
1683- path . join ( FIXTURES , "valid" , "smoke -red-tick.yml" ) ,
1684- path . join ( tmp , "smoke -red-tick.yml" ) ,
1581+ path . join ( FIXTURES , "valid" , "agent -red-tick.yml" ) ,
1582+ path . join ( tmp , "agent -red-tick.yml" ) ,
16851583 ) ;
16861584 // One malformed rule (missing id, fails schema).
16871585 await fs . copyFile (
@@ -1707,7 +1605,7 @@ describe("rule-loader: initial load emits rules.reload.failed on errors (R24 buc
17071605
17081606 // Good rule still loads.
17091607 expect ( rules ) . toHaveLength ( 1 ) ;
1710- expect ( rules [ 0 ] ! . id ) . toBe ( "smoke -red-tick" ) ;
1608+ expect ( rules [ 0 ] ! . id ) . toBe ( "agent -red-tick" ) ;
17111609 // Bad rule surfaces via errors.
17121610 expect ( errors ) . toHaveLength ( 1 ) ;
17131611 expect ( errors [ 0 ] ! . file ) . toBe ( "missing-id.yml" ) ;
0 commit comments