Compare commits
2 Commits
081d40c208
...
50194c72b2
| Author | SHA1 | Date | |
|---|---|---|---|
| 50194c72b2 | |||
| 6bf63f1823 |
@@ -1,7 +1,7 @@
|
|||||||
# Codex Redactor utility — design spec
|
# Codex Redactor utility — design spec
|
||||||
|
|
||||||
> Retroactive: written 2026-05-01.
|
> Retroactive: written 2026-05-01.
|
||||||
> **Status: deferred — not implemented.** This is a forward-looking design captured here for backfill symmetry and to inform iblogs's upload-time PII handling.
|
> **Status: implemented on the `redactor` branch (2026-05-01).** Plan: `docs/superpowers/plans/2026-05-01-redactor.md`. Arrival commit set documented in `CHANGELOG.md` `[Unreleased]`. The "Status: deferred" framing below is preserved for historical context; treat this file as the as-built design contract.
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,38 @@ class ProjectZomboidRedactorIntegrationTest extends TestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Yields [fixturePath] for the subset of fixtures where every synthetic
|
||||||
|
* player name (Player1 / Player2 / AdminUser / PlayerSuspect) appears
|
||||||
|
* exclusively in a context the redactor recognises:
|
||||||
|
*
|
||||||
|
* - chat: ChatMessage{author='...'} envelope
|
||||||
|
* - cmd, item, map, user: 77-char-Steam-ID followed by "..." quoted name
|
||||||
|
*
|
||||||
|
* Fixtures intentionally excluded:
|
||||||
|
*
|
||||||
|
* - admin: names appear in free-text positions (no Steam-ID anchor,
|
||||||
|
* no quotes, no Combat:/Safety: prefix). Names survive in v1.
|
||||||
|
* - client-action,
|
||||||
|
* perk: names appear inside [...] brackets, not "..." quotes.
|
||||||
|
* PLAYER_AFTER_STEAMID_REGEX requires double-quotes.
|
||||||
|
* - pvp: attacker name redacts but victim name after `hit "..."`
|
||||||
|
* survives in v1 (Task 3 limitation).
|
||||||
|
* - burd-journals,
|
||||||
|
* debug-server: no synthetic player names present.
|
||||||
|
*/
|
||||||
|
public static function fixturesWhereAllNamesAreInCoveredContextsProvider(): array
|
||||||
|
{
|
||||||
|
$dir = self::$fixturesDir;
|
||||||
|
return [
|
||||||
|
'chat' => [$dir . '/chat-minimal.txt'],
|
||||||
|
'cmd' => [$dir . '/cmd-minimal.txt'],
|
||||||
|
'item' => [$dir . '/item-minimal.txt'],
|
||||||
|
'map' => [$dir . '/map-minimal.txt'],
|
||||||
|
'user' => [$dir . '/user-minimal.txt'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Yields [fixturePath, logClass] for the fixtures whose log class parses
|
* Yields [fixturePath, logClass] for the fixtures whose log class parses
|
||||||
* them. All 11 fixtures are represented.
|
* them. All 11 fixtures are represented.
|
||||||
@@ -202,4 +234,39 @@ class ProjectZomboidRedactorIntegrationTest extends TestCase
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Test 4 — Player-name collapse in fully-covered fixtures
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For fixtures where every synthetic player name appears exclusively in a
|
||||||
|
* context the redactor recognises, no synthetic name should remain after
|
||||||
|
* redaction.
|
||||||
|
*
|
||||||
|
* This addresses observation #3 from the final code review (the integration
|
||||||
|
* tests previously asserted Steam-ID elimination + structural preservation
|
||||||
|
* + idempotence, but did not directly verify name collapse). The unit tests
|
||||||
|
* in ProjectZomboidRedactorPlayerNameTest cover this property exhaustively
|
||||||
|
* per-context; this integration test re-verifies it end-to-end against the
|
||||||
|
* fixtures that ride into iblogs.
|
||||||
|
*/
|
||||||
|
#[DataProvider('fixturesWhereAllNamesAreInCoveredContextsProvider')]
|
||||||
|
public function testFixturePlayerNamesCollapseInCoveredContexts(string $fixturePath): void
|
||||||
|
{
|
||||||
|
$content = (new PathLogFile($fixturePath))->getContent();
|
||||||
|
$redacted = $this->redact($content);
|
||||||
|
|
||||||
|
foreach (['Player1', 'Player2', 'AdminUser', 'PlayerSuspect'] as $name) {
|
||||||
|
$this->assertStringNotContainsString(
|
||||||
|
$name,
|
||||||
|
$redacted,
|
||||||
|
sprintf(
|
||||||
|
'Fixture "%s": synthetic name %s survived redaction. Every name in this fixture should appear only in a covered lexical context.',
|
||||||
|
basename($fixturePath),
|
||||||
|
$name,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user