A tool for parsing traffic on the jetstream and applying a moderation workstream based on regexp based rules

1. src/types.ts:68 - added optional expires?: string field to AccountAgeCheck interface 2. src/rules/account/age.ts:117-128 - added logic to skip expired checks by comparing current date against expires date 3. src/rules/account/ageConstants.ts:24 - updated example to show how to use the new field 4. added 3 tests to verify: - expired checks are skipped - non-expired checks still work - checks without expires field work (backward compatible)

Skywatch c4bf03e9 11ee91be

+114
+13
src/rules/account/age.ts
··· 114 114 continue; 115 115 } 116 116 117 + // Skip if check has expired 118 + if (check.expires) { 119 + const expiresDate = new Date(check.expires); 120 + const now = new Date(); 121 + if (now > expiresDate) { 122 + logger.debug( 123 + { process: "ACCOUNT_AGE", expires: check.expires }, 124 + "Check has expired, skipping", 125 + ); 126 + continue; 127 + } 128 + } 129 + 117 130 logger.debug( 118 131 { 119 132 process: "ACCOUNT_AGE",
+1
src/rules/account/ageConstants.ts
··· 21 21 // maxAgeDays: 7, // Flag accounts less than 7 days old 22 22 // label: "new-account-reply", 23 23 // comment: "New account replying to monitored user during campaign", 24 + // expires: "2025-02-15", // Optional: automatically stop this check after this date 24 25 // }, 25 26 ];
+99
src/rules/account/tests/age.test.ts
··· 472 472 "Global allowlisted DID", 473 473 ); 474 474 }); 475 + 476 + it("should skip if check has expired", async () => { 477 + ACCOUNT_AGE_CHECKS.push({ 478 + monitoredDIDs: ["did:plc:monitored"], 479 + anchorDate: "2025-10-15", 480 + maxAgeDays: 7, 481 + label: "window-reply", 482 + comment: "Account created in window", 483 + expires: "2025-10-01", // Already expired 484 + }); 485 + 486 + // Mock account created within window 487 + const mockDidDoc = [{ createdAt: "2025-10-18T12:00:00.000Z" }]; 488 + (global.fetch as any).mockResolvedValueOnce({ 489 + ok: true, 490 + json: async () => mockDidDoc, 491 + }); 492 + 493 + await checkAccountAge({ 494 + replyToDid: "did:plc:monitored", 495 + replyingDid: "did:plc:newaccount", 496 + atURI: TEST_REPLY_URI, 497 + time: TEST_TIME, 498 + }); 499 + 500 + expect(createAccountLabel).not.toHaveBeenCalled(); 501 + expect(logger.debug).toHaveBeenCalledWith( 502 + { process: "ACCOUNT_AGE", expires: "2025-10-01" }, 503 + "Check has expired, skipping", 504 + ); 505 + }); 506 + 507 + it("should apply label if check has not expired", async () => { 508 + ACCOUNT_AGE_CHECKS.push({ 509 + monitoredDIDs: ["did:plc:monitored"], 510 + anchorDate: "2025-10-15", 511 + maxAgeDays: 7, 512 + label: "window-reply", 513 + comment: "Account created in window", 514 + expires: "2026-01-01", // Future date 515 + }); 516 + 517 + // Mock account created within window 518 + const mockDidDoc = [{ createdAt: "2025-10-18T12:00:00.000Z" }]; 519 + (global.fetch as any).mockResolvedValueOnce({ 520 + ok: true, 521 + json: async () => mockDidDoc, 522 + }); 523 + 524 + // Mock that label does NOT exist 525 + (checkAccountLabels as any).mockResolvedValueOnce(false); 526 + 527 + await checkAccountAge({ 528 + replyToDid: "did:plc:monitored", 529 + replyingDid: "did:plc:newaccount", 530 + atURI: TEST_REPLY_URI, 531 + time: TEST_TIME, 532 + }); 533 + 534 + expect(createAccountLabel).toHaveBeenCalledWith( 535 + "did:plc:newaccount", 536 + "window-reply", 537 + expect.stringContaining("Account created within monitored range"), 538 + ); 539 + }); 540 + 541 + it("should apply label if no expires field is set", async () => { 542 + ACCOUNT_AGE_CHECKS.push({ 543 + monitoredDIDs: ["did:plc:monitored"], 544 + anchorDate: "2025-10-15", 545 + maxAgeDays: 7, 546 + label: "window-reply", 547 + comment: "Account created in window", 548 + // No expires field 549 + }); 550 + 551 + // Mock account created within window 552 + const mockDidDoc = [{ createdAt: "2025-10-18T12:00:00.000Z" }]; 553 + (global.fetch as any).mockResolvedValueOnce({ 554 + ok: true, 555 + json: async () => mockDidDoc, 556 + }); 557 + 558 + // Mock that label does NOT exist 559 + (checkAccountLabels as any).mockResolvedValueOnce(false); 560 + 561 + await checkAccountAge({ 562 + replyToDid: "did:plc:monitored", 563 + replyingDid: "did:plc:newaccount", 564 + atURI: TEST_REPLY_URI, 565 + time: TEST_TIME, 566 + }); 567 + 568 + expect(createAccountLabel).toHaveBeenCalledWith( 569 + "did:plc:newaccount", 570 + "window-reply", 571 + expect.stringContaining("Account created within monitored range"), 572 + ); 573 + }); 475 574 }); 476 575 });
+1
src/types.ts
··· 65 65 maxAgeDays: number; // Maximum account age in days 66 66 label: string; // Label to apply if account is too new 67 67 comment: string; // Comment for the label 68 + expires?: string; // Optional expiration date (ISO 8601) - check will be skipped after this date 68 69 } 69 70