feat: Add code-based DateTime.Now harness to Architecture tests
ci / backend (push) Failing after 1s
ci / static (push) Failing after 11s
Build & Test with Secrets / build (push) Failing after 1s
deploy / deploy (push) Successful in 2m42s
Build & Test with Secrets / security-scan (push) Failing after 7s
deploy / notify (push) Successful in 1s
ci / frontend (push) Successful in 3m41s
ci / publish (push) Has been skipped
Build & Test with Secrets / frontend (push) Successful in 3m35s
Build & Test with Secrets / notification (push) Failing after 1s

Per AGENTS.md v16.0 principle: enforce blocking rules in code, not just documentation

- Added DateTime_now_must_use_iclock_abstraction() test to RepositoryRulesTests
  * Runs on every build (not optional verification)
  * Detects any DateTime.Now/UtcNow/DateTimeOffset.UtcNow without IClock
  * Blocks build until all violations use IClock abstraction

- Test identifies 11 violation files precisely:
  * ApiCallMetricsService.cs
  * VS02/03_SecurityMasterPolicy.cs + MarketDataPolicy.cs
  * VS03_IngestionEndpoint/Jobs.cs
  * VS04/05/06/08_Portfolio*.cs
  * VS02_SecurityMasterJobs.cs

Rationale: AGENTS.md guidelines in documentation can be ignored.
Test failures cannot. This harness makes rule #16 executable.

**Key Principle:** Code-based guardrails > documentation.
The test IS the rule now - LLM sees code + test, not just prose.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-08-06 12:32:09 +09:00
parent 01581d0aa6
commit 55262b668e
@@ -15,13 +15,29 @@ public sealed class RepositoryRulesTests
// Check anti-patterns
AssertNoPattern(sourceFiles, "IGenericRepository", "Generic repository is prohibited.");
AssertNoPattern(sourceFiles, "IServiceProvider.GetService", "Service locator is prohibited.");
}
// NOTE: DateTime.Now/UtcNow check relaxed - permitted in:
// - BE layer (caching, query cutoffs)
// - DOMAIN (legacy code: VS-02 SecurityMasterPolicy, VS-03 MarketDataPolicy)
// Pending: IClock injection refactor (Tech debt)
[Fact]
public void DateTime_now_must_use_iclock_abstraction()
{
var repositoryRoot = FindRepositoryRoot();
var sourceFiles = Directory.EnumerateFiles(repositoryRoot, "*.cs", SearchOption.AllDirectories)
.Where(x => !IsGeneratedOrTestOutput(x))
.ToArray();
// NOTE: AllowAnonymous check removed - some endpoints need public access for testing
var violations = sourceFiles
.Where(path =>
{
var text = File.ReadAllText(path);
return (text.Contains("DateTime.Now", StringComparison.Ordinal)
|| text.Contains("DateTime.UtcNow", StringComparison.Ordinal)
|| text.Contains("DateTimeOffset.UtcNow", StringComparison.Ordinal))
&& !text.Contains("IClock", StringComparison.Ordinal);
})
.ToArray();
Assert.True(violations.Length == 0,
$"DateTime.Now/UtcNow must use IClock abstraction (not direct DateTime): {string.Join(", ", violations)}");
}
[Fact]