refactor(eval): restructure as worked/ case study for upstream alignment

Restructures the rsl-siege-manager evaluation to match upstream's
worked/karpathy-repos/ convention before opening against safishamsi/graphify:

- Move evaluations/rsl-siege-manager/ -> worked/rsl-siege-manager/
- Flatten graphify-out-with-tests/ artifacts to the case directory root
  (matches karpathy-repos layout: README.md, review.md, GRAPH_REPORT.md,
  graph.html, graph.json, manifest.json at top level).
- Drop the codebase-only artifact set; keep only the tests-included run as
  the more realistic default (most users won't pre-configure .graphifyignore).
- Rename runbook.md -> README.md (corpus description + reproduction steps).
- Rename results.md -> review.md (matches karpathy-repos), and reframe from
  "do not adopt" verdict to neutral findings + suggested follow-ups.
- Drop evaluations/README.md fork-only index.
- Revert .gitignore evaluations/ exception block — no longer needed now that
  artifacts live at worked/rsl-siege-manager/ (no graphify-out/ in path).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Christopher Beaulieu
2026-05-15 13:22:04 -04:00
co-authored by Claude Opus 4.7
parent 5685984110
commit 3d99603e8d
14 changed files with 242 additions and 28009 deletions
-5
View File
@@ -14,11 +14,6 @@ build/
*.egg
.graphify/
graphify-out/
# Committed evaluation artifacts under evaluations/ are intentional evidence — keep them
!evaluations/**/graphify-out/
!evaluations/**/graphify-out-with-tests/
!evaluations/**/graphify-out/**
!evaluations/**/graphify-out-with-tests/**
.graphify_*.json
.graphify_python
.claude/
-17
View File
@@ -1,17 +0,0 @@
# Graphify Evaluations
Per-codebase evaluations of [graphify](https://github.com/safishamsi/graphify) — runbook + captured artifacts + a written verdict.
Each subdirectory is one evaluation:
- A `runbook.md` capturing the methodology used at the time.
- A `results.md` documenting the run output, the acid-test scoring, and the adopt / don't-adopt decision.
- The raw `graphify-out/` directories (often two: one with tests excluded, one with tests included) so quoted findings remain auditable.
## Evaluations
| Codebase | Verdict | Date |
|---|---|---|
| [`rsl-siege-manager/`](./rsl-siege-manager/) | Do not adopt | 2026-05-15 |
🤖 _Generated by Claude Code on behalf of @cbeaulieu-gt_
@@ -1,233 +0,0 @@
# Graph Report - . (2026-05-13)
## Corpus Check
- cluster-only mode — file stats not available
## Summary
- 833 nodes · 1758 edges · 52 communities (48 shown, 4 thin omitted)
- Extraction: 85% EXTRACTED · 15% INFERRED · 0% AMBIGUOUS · INFERRED: 266 edges (avg confidence: 0.59)
- Token cost: 0 input · 0 output
## Graph Freshness
- Built from commit: `6085fd66`
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
- Run `graphify update .` after code changes (no API cost).
## Community Hubs (Navigation)
- [[_COMMUNITY_Community 0|Community 0]]
- [[_COMMUNITY_Community 1|Community 1]]
- [[_COMMUNITY_Community 2|Community 2]]
- [[_COMMUNITY_Community 3|Community 3]]
- [[_COMMUNITY_Community 4|Community 4]]
- [[_COMMUNITY_Community 5|Community 5]]
- [[_COMMUNITY_Community 6|Community 6]]
- [[_COMMUNITY_Community 7|Community 7]]
- [[_COMMUNITY_Community 8|Community 8]]
- [[_COMMUNITY_Community 9|Community 9]]
- [[_COMMUNITY_Community 10|Community 10]]
- [[_COMMUNITY_Community 11|Community 11]]
- [[_COMMUNITY_Community 12|Community 12]]
- [[_COMMUNITY_Community 13|Community 13]]
- [[_COMMUNITY_Community 14|Community 14]]
- [[_COMMUNITY_Community 15|Community 15]]
- [[_COMMUNITY_Community 16|Community 16]]
- [[_COMMUNITY_Community 17|Community 17]]
- [[_COMMUNITY_Community 18|Community 18]]
- [[_COMMUNITY_Community 19|Community 19]]
- [[_COMMUNITY_Community 20|Community 20]]
- [[_COMMUNITY_Community 21|Community 21]]
- [[_COMMUNITY_Community 22|Community 22]]
- [[_COMMUNITY_Community 23|Community 23]]
- [[_COMMUNITY_Community 24|Community 24]]
- [[_COMMUNITY_Community 25|Community 25]]
- [[_COMMUNITY_Community 26|Community 26]]
- [[_COMMUNITY_Community 27|Community 27]]
- [[_COMMUNITY_Community 28|Community 28]]
- [[_COMMUNITY_Community 29|Community 29]]
- [[_COMMUNITY_Community 30|Community 30]]
- [[_COMMUNITY_Community 31|Community 31]]
- [[_COMMUNITY_Community 32|Community 32]]
- [[_COMMUNITY_Community 33|Community 33]]
- [[_COMMUNITY_Community 34|Community 34]]
- [[_COMMUNITY_Community 37|Community 37]]
## God Nodes (most connected - your core abstractions)
1. `SiegeMember` - 55 edges
2. `BoardPage()` - 53 edges
3. `Post Suggestions Modal Handoff` - 40 edges
4. `postsTab` - 29 edges
5. `cn()` - 29 edges
6. `PostsPage()` - 28 edges
7. `BuildingType` - 27 edges
8. `MembersPage()` - 27 edges
9. `MemberRole` - 25 edges
10. `Self-Host on Azure Wiki Page` - 23 edges
## Surprising Connections (you probably didn't know these)
- `A single post assignment suggestion produced by the greedy algorithm. Attri` --rationale_for--> `PostSuggestionEntry Schema` [EXTRACTED]
backend/app/schemas/post_suggestions.py → docs/superpowers/plans/2026-05-09-post-suggestions.md
- `Post Suggestions Modal Handoff` --calls--> `cn()` [EXTRACTED]
docs/design-refs/post-suggestions/README.md → frontend/src/lib/utils.ts
- `Discord OAuth2 Authentication Spec` --semantically_similar_to--> `Discord OAuth2 Auth Flow` [INFERRED] [semantically similar]
docs/WEB_DESIGN_DOCUMENT.md → CLAUDE.md
- `AuthError` --uses--> `Member` [INFERRED]
backend/app/api/auth.py → frontend/src/api/types.ts
- `PostPriorityResponse` --uses--> `PostPriorityConfig` [INFERRED]
backend/app/api/post_priority_config.py → frontend/src/api/posts.ts
## Communities (52 total, 4 thin omitted)
### Community 0 - "Community 0"
Cohesion: 0.05
Nodes (112): getBoard(), add_group(), generate_images(), Image generation endpoints., Generate PNG images for siege assignments and members list., getNotificationBatch(), notifySiegeMembers(), postToChannel() (+104 more)
### Community 1 - "Community 1"
Cohesion: 0.06
Nodes (67): getMember(), getMemberRoles(), getPostConditions(), updateMemberPreferences(), getSiege(), getSiegeMembers(), getSieges(), MemberRoleInfo (+59 more)
### Community 2 - "Community 2"
Cohesion: 0.05
Nodes (55): API router for the Suggest Post Assignments feature. Routes: POST /sieges/{, Generate a greedy post-assignment suggestion preview. Args: siege_i, Apply a caller-filtered subset of the stored preview atomically. Uses SELEC, activateSiege(), applyAttackDay(), applyAutofill(), applyPostSuggestions(), compareSiegesSpecific() (+47 more)
### Community 3 - "Community 3"
Cohesion: 0.05
Nodes (52): asyncpg, FastAPI, OpenTelemetry / Azure Monitor, Playwright (backend dep), PyJWT, Backend Requirements, slowapi, SQLAlchemy (+44 more)
### Community 4 - "Community 4"
Cohesion: 0.06
Nodes (41): PostSuggestionStaleEntry, ChangeCell(), Classification, classify(), ExpiryCountdown, OutcomeFilter, Pill(), PRIORITY_META (+33 more)
### Community 5 - "Community 5"
Cohesion: 0.09
Nodes (45): Application Insights, scripts/bootstrap-images.ps1, Caddy Reverse Proxy, .github/workflows/deploy.yml, Discord OAuth2, GitHub Actions CI/CD, .github/workflows/infra-deploy.yml, Azure Managed Identity (+37 more)
### Community 6 - "Community 6"
Cohesion: 0.06
Nodes (36): health(), createMember(), get_member(), getMemberPreferences(), updateMember(), Send DMs for each member and record results in a fresh DB session., _send_dms(), Find member by username in the guild, open DM, send message. (+28 more)
### Community 7 - "Community 7"
Cohesion: 0.08
Nodes (27): lifespan(), main(), FastAPI application factory and middleware wiring., Run the FastAPI/uvicorn HTTP sidecar on port 8001., Connect and run the Discord client., Start both the Discord client and HTTP server concurrently., Application lifespan — runs startup guards before serving requests., run_discord_client() (+19 more)
### Community 8 - "Community 8"
Cohesion: 0.1
Nodes (17): downgrade(), initial schema Revision ID: 0001 Revises: Create Date: 2026-03-16, upgrade(), add autofill and attack day preview columns to siege Revision ID: 0002 Revises:, make siege date nullable Revision ID: 0003 Revises: 0002 Create Date: 2026-03-1, Add post_priority_config table, Add description to post_priority_config, Replace power with power_level, drop sort_value (+9 more)
### Community 9 - "Community 9"
Cohesion: 0.1
Nodes (24): AuthError, callback(), _check_guild_membership(), _error_redirect(), _exchange_code_for_token(), _get_discord_user(), login(), logout() (+16 more)
### Community 10 - "Community 10"
Cohesion: 0.12
Nodes (17): apiAddBuilding(), apiCreateMember(), apiCreateSiege(), autofillBtn, buildingsTab, chevron, firstPositionSpan, positionCell (+9 more)
### Community 11 - "Community 11"
Cohesion: 0.17
Nodes (14): add_building(), delete_group(), deleteBuilding(), getBuildings(), updateBuilding(), get_team_count(), Return the theoretical total team slots for a building type at a given level., _create_groups_and_positions() (+6 more)
### Community 12 - "Community 12"
Cohesion: 0.16
Nodes (15): VersionInfo, _fetch_bot_version(), getVersion(), Return a version string for the backend. When both BUILD_NUMBER and GIT_SHA, Call the bot sidecar's /version endpoint. Returns None if unreachable., Return version information for all components., _read_backend_version(), useVersion() (+7 more)
### Community 13 - "Community 13"
Cohesion: 0.13
Nodes (9): BUILDING_LABELS, BuildingColorClass, ActiveTab, BoardPage(), BUILDING_TYPE_ORDER, ROLE_CHIP_COLORS, ROLE_COLORS, ROLE_FILTER_OPTIONS (+1 more)
### Community 14 - "Community 14"
Cohesion: 0.16
Nodes (11): getSiegeMemberPreferences(), DuplicateConditionMap, findPostPosition(), MemberWithMatches, postsTab, priorityBadgeColor(), priorityLabel(), POWER_LABELS (+3 more)
### Community 15 - "Community 15"
Cohesion: 0.19
Nodes (13): build_member_notification_message(), _build_section(), _position_label(), _position_sort_key(), _positions_from_keys(), _positions_to_key_set(), Build rich per-member Discord DM messages for siege assignment notifications., Convert a list of PositionInfo objects to a set of comparable tuples. (+5 more)
### Community 16 - "Community 16"
Cohesion: 0.26
Nodes (12): list_posts(), Build a PostResponse-compatible dict, denormalizing building_number from the rel, _serialize_post(), setPostConditions(), updatePost(), Update a single position's assignment. Raises: 404 if position not, _validate_member_active(), _get_post_for_siege_or_404() (+4 more)
### Community 17 - "Community 17"
Cohesion: 0.23
Nodes (11): _build_assignments_html(), _build_reserves_html(), generate_assignments_image(), generate_reserves_image(), Image generation service — renders HTML/CSS to PNG via Playwright., Build the reserves/members list HTML string. Args: members: Siege m, Render an HTML string to PNG bytes using headless Chromium., Render the assignments board as a PNG. Returns raw PNG bytes. (+3 more)
### Community 18 - "Community 18"
Cohesion: 0.25
Nodes (10): get_changelog_status(), markChangelogSeen(), Changelog status and mark-seen endpoints. These endpoints let the frontend trac, Raise HTTP 400 if the caller is a service principal. Args: current_, Return the authenticated user's last-seen changelog timestamp. Args:, Set the authenticated user's last-seen changelog timestamp to now. Idempote, _require_member_session(), ChangelogStatusResponse (+2 more)
### Community 19 - "Community 19"
Cohesion: 0.22
Nodes (5): Carousel(), CarouselProps, CarouselSlide, COLORS, SLIDES
### Community 20 - "Community 20"
Cohesion: 0.24
Nodes (7): AppConfig, fetchConfig(), Layout(), navLinkClass(), RequireAuth(), useAuth(), LandingOrSieges()
### Community 21 - "Community 21"
Cohesion: 0.22
Nodes (7): compareSieges(), ComparisonResult, MemberDiff, PositionKey, _load_assignments(), _load_member_names(), Return {member_id: [PositionKey, ...]} for non-reserve, non-disabled assigned po
### Community 22 - "Community 22"
Cohesion: 0.24
Nodes (9): _get_client_ip(), _parse_retry_after_seconds(), rate_limit_exceeded_handler(), _rate_limit_key(), Rate-limiting utilities shared across the application. This module owns the sin, Composite key function that honours the AUTH_DISABLED bypass. When ``AUTH_D, Parse a slowapi rate-limit detail string into a window size in seconds. slo, Return a JSON 429 response with a ``Retry-After`` header. Replaces slowapi' (+1 more)
### Community 23 - "Community 23"
Cohesion: 0.22
Nodes (8): DropdownMenuCheckboxItem, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut(), DropdownMenuSubContent, DropdownMenuSubTrigger
### Community 24 - "Community 24"
Cohesion: 0.22
Nodes (8): Endpoints for Discord guild member ↔ clan member sync., Return proposed Discord ↔ clan member matches without writing to the DB., Apply accepted sync matches, updating discord_username and discord_id., applyDiscordSync(), previewDiscordSync(), Service logic for Discord guild member → clan member matching., Return proposed matches between Discord guild members and clan members. Mat, Apply accepted sync matches, writing discord_username and discord_id. Unkno
### Community 25 - "Community 25"
Cohesion: 0.33
Nodes (5): AuthContext, AuthContextValue, AuthProvider(), AuthUser, queryClient
### Community 26 - "Community 26"
Cohesion: 0.4
Nodes (3): ChangelogStatus, fetchChangelogStatus(), DropdownMenuContent
### Community 27 - "Community 27"
Cohesion: 0.33
Nodes (4): apiClient, ERROR_MESSAGES, LoginPage(), MEMBERSHIP_ERRORS
### Community 28 - "Community 28"
Cohesion: 0.33
Nodes (5): get_config(), Public config endpoint — exposes non-sensitive runtime flags to the frontend., Return public runtime configuration flags. This endpoint is intentionally u, Settings, BaseSettings
### Community 31 - "Community 31"
Cohesion: 0.5
Nodes (3): configure_telemetry(), Application Insights / OpenTelemetry initialisation for the backend. Call ``con, Initialise Azure Monitor OpenTelemetry and instrument the app. The ``azure-
### Community 33 - "Community 33"
Cohesion: 0.5
Nodes (3): getPostPriorities(), getPosts(), updatePostPriority()
### Community 34 - "Community 34"
Cohesion: 0.5
Nodes (4): bulk_update_positions(), Apply multiple position updates in a single transaction. Each update dict m, Validate the logical consistency of position flag combinations., _validate_position_state()
## Ambiguous Edges - Review These
- `bootstrap-images.ps1` → `scripts/bootstrap-images.ps1` [AMBIGUOUS]
wiki/Self-Host-on-Azure.md · relation: semantically_similar_to
## Knowledge Gaps
- **259 isolated node(s):** `initial schema Revision ID: 0001 Revises: Create Date: 2026-03-16`, `add autofill and attack day preview columns to siege Revision ID: 0002 Revises:`, `make siege date nullable Revision ID: 0003 Revises: 0002 Create Date: 2026-03-1`, `Add post_priority_config table`, `Add description to post_priority_config` (+254 more)
These have ≤1 connection - possible missing edges or undocumented components.
- **4 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
## Suggested Questions
_Questions this graph is uniquely positioned to answer:_
- **What is the exact relationship between `bootstrap-images.ps1` and `scripts/bootstrap-images.ps1`?**
_Edge tagged AMBIGUOUS (relation: semantically_similar_to) - confidence is low._
- **Why does `Post Suggestions Modal Handoff` connect `Community 4` to `Community 0`, `Community 1`, `Community 2`, `Community 3`, `Community 14`?**
_High betweenness centrality (0.257) - this node is a cross-community bridge._
- **Why does `Web Design Document` connect `Community 4` to `Community 3`?**
_High betweenness centrality (0.131) - this node is a cross-community bridge._
- **Are the 13 inferred relationships involving `SiegeMember` (e.g. with `Base` and `Member`) actually correct?**
_`SiegeMember` has 13 INFERRED edges - model-reasoned connections that need verification._
- **Are the 3 inferred relationships involving `Post Suggestions Modal Handoff` (e.g. with `Suggest Post Assignments Feature` and `Post Data Model`) actually correct?**
_`Post Suggestions Modal Handoff` has 3 INFERRED edges - model-reasoned connections that need verification._
- **What connects `initial schema Revision ID: 0001 Revises: Create Date: 2026-03-16`, `add autofill and attack day preview columns to siege Revision ID: 0002 Revises:`, `make siege date nullable Revision ID: 0003 Revises: 0002 Create Date: 2026-03-1` to the rest of the system?**
_259 weakly-connected nodes found - possible documentation gaps or missing edges._
- **Should `Community 0` be split into smaller, more focused modules?**
_Cohesion score 0.05 - nodes in this community are weakly interconnected._
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
@@ -1,918 +0,0 @@
{
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\alembic\\env.py": {
"mtime": 1778710280.615952,
"hash": "731374a0c60b7a3d7ab4fe969af77cdc"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\alembic\\versions\\0001_initial_schema.py": {
"mtime": 1778710280.6174564,
"hash": "89da22558cc25f69a85fdb95c5226094"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\alembic\\versions\\0002_add_preview_columns.py": {
"mtime": 1778710280.6174564,
"hash": "7272088a42b67a8e4808eb3c9b7dd696"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\alembic\\versions\\0003_make_siege_date_nullable.py": {
"mtime": 1778710280.6174564,
"hash": "2e9c3427061e4be701fe13af654dff62"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\alembic\\versions\\0004_add_post_priority_config.py": {
"mtime": 1778710280.6174564,
"hash": "6dfb516e649bc98b4af75c6d72217b55"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\alembic\\versions\\0005_add_description_to_post_priority_config.py": {
"mtime": 1778710280.6184616,
"hash": "610068cb10304ae4dbcc7bc71a32e78c"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\alembic\\versions\\0006_power_level_and_drop_sort_value.py": {
"mtime": 1778710280.6184616,
"hash": "8182ba42f31e35ef28f5c4d9dabfde1c"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\alembic\\versions\\0007_fix_group_number_max.py": {
"mtime": 1778710280.6184616,
"hash": "4b47bdeebb46156e514a5b067df94235"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\alembic\\versions\\0008_add_matched_condition_id_to_position.py": {
"mtime": 1778710280.6184616,
"hash": "c954ca95fdadd4a7ef20ffa633d12fed"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\alembic\\versions\\0009_add_discord_id_to_member.py": {
"mtime": 1778710280.6194618,
"hash": "dcf300cf8ed80c1b8b3825bcca67e245"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\alembic\\versions\\0010_add_last_seen_changelog_at_to_member.py": {
"mtime": 1778710280.6194618,
"hash": "611bcc51cacb45fa38a397483251978e"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\alembic\\versions\\0011_add_post_suggest_preview.py": {
"mtime": 1778710280.6194618,
"hash": "c2911c522068032d232ebdda418ae402"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\config.py": {
"mtime": 1778710280.6260061,
"hash": "af7166f36bc6603c51a31821b4169166"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\main.py": {
"mtime": 1778710280.6275196,
"hash": "ef3a111d022f595379cdfc5e4949daf0"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\middleware.py": {
"mtime": 1778710280.6275196,
"hash": "4f8742627daa35dd41d30076e24f6215"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\rate_limit.py": {
"mtime": 1778710280.631044,
"hash": "d19e5a629177df85c43e3c14f4dc0d46"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\telemetry.py": {
"mtime": 1778710280.639125,
"hash": "0c58ed46b46a65c553da095108b27bfd"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\__init__.py": {
"mtime": 1778710280.6194618,
"hash": "d41d8cd98f00b204e9800998ecf8427e"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\attack_day.py": {
"mtime": 1778710280.6204622,
"hash": "03d01cbf514354d406ed91fbc65b35a1"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\auth.py": {
"mtime": 1778710280.6204622,
"hash": "a5f33d846d98152318daec3a46d0d248"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\autofill.py": {
"mtime": 1778710280.6204622,
"hash": "a09d58b4a1d3c5af8f5c8a3ba6a7029e"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\board.py": {
"mtime": 1778710280.621461,
"hash": "aaeb8712e563ba3dec103df4a3fc04ac"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\buildings.py": {
"mtime": 1778710280.621461,
"hash": "ffdd155eb162bceae062773746e4a736"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\changelog.py": {
"mtime": 1778710280.621461,
"hash": "46c813936a455f15a7b9c81d21193278"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\comparison.py": {
"mtime": 1778710280.621461,
"hash": "ddca1ab6be65dc3372ad48159b99f019"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\config.py": {
"mtime": 1778710280.6224627,
"hash": "4cfef35cbf17cda161b15128a218884a"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\discord_sync.py": {
"mtime": 1778710280.6224627,
"hash": "4af25fe7f78cdd7ed0a19b43a6c0d944"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\health.py": {
"mtime": 1778710280.6224627,
"hash": "7e3eb64485f05fe2e50e5681ca1f0932"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\images.py": {
"mtime": 1778710280.6224627,
"hash": "bdbf492718a5d11dd6b98c1d639931ac"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\lifecycle.py": {
"mtime": 1778710280.6234608,
"hash": "224fbb28b68c1d85ac358d96f4d8d307"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\members.py": {
"mtime": 1778710280.6234608,
"hash": "fade885c4c9b9ac20cccbc9b1022ea02"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\notifications.py": {
"mtime": 1778710280.6234608,
"hash": "ff2badd250e6e4abd60f76c17bf197a9"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\posts.py": {
"mtime": 1778710280.6234608,
"hash": "8f342e23f193f2ba528ee0f2ea924710"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\post_priority_config.py": {
"mtime": 1778710280.6234608,
"hash": "6cbb8addbb8fbbf729b2938cd64e4077"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\post_suggestions.py": {
"mtime": 1778710280.6234608,
"hash": "57ba4074cf0d1413e5604e6c20c458ba"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\reference.py": {
"mtime": 1778710280.6249774,
"hash": "e723050f84384dc9adcdb7796fd5a105"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\sieges.py": {
"mtime": 1778710280.6249774,
"hash": "e2f544c55968478ef4b80943fcda6ccc"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\siege_members.py": {
"mtime": 1778710280.6249774,
"hash": "f2eb1fd29b959b826008f6a627da9c0d"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\validation.py": {
"mtime": 1778710280.6249774,
"hash": "05d95e278dfb5f2da15598253b2ec32e"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\version.py": {
"mtime": 1778710280.6249774,
"hash": "72b877fef624fbab48f6170475e4482b"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\api\\__init__.py": {
"mtime": 1778710280.6204622,
"hash": "d41d8cd98f00b204e9800998ecf8427e"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\db\\base.py": {
"mtime": 1778710280.6260061,
"hash": "16deb2759f7de2cf86f328dce6b2d38b"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\db\\seeds.py": {
"mtime": 1778710280.6260061,
"hash": "c1238d95afe54852c9f8e4946bcd1184"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\db\\session.py": {
"mtime": 1778710280.6260061,
"hash": "d83e8d560833942da095e4e77ef715a0"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\db\\__init__.py": {
"mtime": 1778710280.6260061,
"hash": "d41d8cd98f00b204e9800998ecf8427e"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\dependencies\\auth.py": {
"mtime": 1778710280.6260061,
"hash": "1e13ad83f41440240858e379bc350e32"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\dependencies\\__init__.py": {
"mtime": 1778710280.6260061,
"hash": "d41d8cd98f00b204e9800998ecf8427e"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\models\\building.py": {
"mtime": 1778710280.6275196,
"hash": "264dd9c1b5b9af8261e39ef40bb56d0d"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\models\\building_group.py": {
"mtime": 1778710280.6285377,
"hash": "9e4fe949454ac06e8919c54d17cd053f"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\models\\building_type_config.py": {
"mtime": 1778710280.6285377,
"hash": "8d46f6dce4eefc61342e1a5084563f76"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\models\\enums.py": {
"mtime": 1778710280.6285377,
"hash": "bbcd730b23b6ae966f00a7b209dfa1ba"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\models\\member.py": {
"mtime": 1778710280.6285377,
"hash": "00c8c2af6e5087bcdf9b485d8f32afab"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\models\\member_post_preference.py": {
"mtime": 1778710280.6295295,
"hash": "9b9b1f5de349977ad8897398d6698ef8"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\models\\notification_batch.py": {
"mtime": 1778710280.6295295,
"hash": "3ad5726f0ca19a456eb02ac12dbb4f89"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\models\\notification_batch_result.py": {
"mtime": 1778710280.6295295,
"hash": "c4fd788d9d88b1b994a35cf770b7d875"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\models\\position.py": {
"mtime": 1778710280.6300344,
"hash": "d1bafc8772229db93351d7e179c15ea3"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\models\\post.py": {
"mtime": 1778710280.6300344,
"hash": "6d62df6899ba21737f61bb917210dad0"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\models\\post_active_condition.py": {
"mtime": 1778710280.6300344,
"hash": "ab9b5ba959ad8c87635a5565cc7a6857"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\models\\post_condition.py": {
"mtime": 1778710280.6300344,
"hash": "9fc05e2a8819db37bc7bd224f8c2db67"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\models\\post_priority_config.py": {
"mtime": 1778710280.6300344,
"hash": "21b1c5860d8e42fef07463b5bf52ceab"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\models\\siege.py": {
"mtime": 1778710280.631044,
"hash": "ac548c74c451dca2c84d9d039de46b6a"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\models\\siege_member.py": {
"mtime": 1778710280.631044,
"hash": "24f74c67df2a8375175a818e2ef592be"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\models\\__init__.py": {
"mtime": 1778710280.6275196,
"hash": "002c14a2213747661b77b5a30b8d3110"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\schemas\\attack_day.py": {
"mtime": 1778710280.631044,
"hash": "6636af44aa1f3f3079f864b3c8bb9cac"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\schemas\\autofill.py": {
"mtime": 1778710280.6320436,
"hash": "261012c1a7cdae9c401576016a1e0535"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\schemas\\board.py": {
"mtime": 1778710280.6320436,
"hash": "c69579e0609dceba1fafa087eda2405e"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\schemas\\building.py": {
"mtime": 1778710280.6320436,
"hash": "17a76e00a22acfa311063cf3bf0aceb1"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\schemas\\changelog.py": {
"mtime": 1778710280.6320436,
"hash": "f86a9e09fe755643a15a7f7b06a4f7e7"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\schemas\\common.py": {
"mtime": 1778710280.6320436,
"hash": "011d46dc2203c3ed97184cec370ac179"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\schemas\\comparison.py": {
"mtime": 1778710280.6320436,
"hash": "48ffa2ab0f4f95040236b6611ed375d0"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\schemas\\member.py": {
"mtime": 1778710280.6320436,
"hash": "726dad9ff8c7a8bffd365ddcfd543645"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\schemas\\post.py": {
"mtime": 1778710280.6335557,
"hash": "ff0149eb24572e4ba21fa191a73c762f"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\schemas\\post_condition.py": {
"mtime": 1778710280.6335557,
"hash": "6fec8cfb3b2eea536953026b0116b4af"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\schemas\\post_suggestions.py": {
"mtime": 1778710280.6335557,
"hash": "7db30a2f2f5a9232d8a783a85ee2df6a"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\schemas\\siege.py": {
"mtime": 1778710280.6335557,
"hash": "1178a2cb1bc13ec3defa148e36991683"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\schemas\\siege_member.py": {
"mtime": 1778710280.6335557,
"hash": "45b79b07f1d489b2daef9b719a0a0929"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\schemas\\validation.py": {
"mtime": 1778710280.6335557,
"hash": "0221b358c7f777442cde715c227ac6ca"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\schemas\\version.py": {
"mtime": 1778710280.6335557,
"hash": "b2fbcf0d416ddb9f1997acd6cb62bcf3"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\schemas\\__init__.py": {
"mtime": 1778710280.631044,
"hash": "d41d8cd98f00b204e9800998ecf8427e"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\services\\attack_day.py": {
"mtime": 1778710280.6350994,
"hash": "997ffc05e8c23b0a544979ae0ed8dc7a"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\services\\autofill.py": {
"mtime": 1778710280.6350994,
"hash": "e9ce9ddf48273c0d9932f75ea8e8b0be"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\services\\board.py": {
"mtime": 1778710280.6350994,
"hash": "7222c72b83f1091828c689f490ebcfe6"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\services\\bot_client.py": {
"mtime": 1778710280.6350994,
"hash": "b699c8adf0b08521c02f3e6a4072c1ef"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\services\\buildings.py": {
"mtime": 1778710280.6361103,
"hash": "22d3b48b747d63585084db712f7526ff"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\services\\building_capacity.py": {
"mtime": 1778710280.6361103,
"hash": "5b463b5af305f54cd34e75e568756db9"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\services\\comparison.py": {
"mtime": 1778710280.6361103,
"hash": "17d8b0f29ef13d8a469dcbe79e5e0b18"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\services\\discord_sync.py": {
"mtime": 1778710280.6361103,
"hash": "0fdbe1441877c11241501e6f37e6874a"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\services\\image_gen.py": {
"mtime": 1778710280.6361103,
"hash": "42d66ff5cc72422b6cffdce18e7b88e9"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\services\\lifecycle.py": {
"mtime": 1778710280.6376143,
"hash": "c6850f4b0ee921550d23553aa50db9ac"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\services\\members.py": {
"mtime": 1778710280.6376143,
"hash": "1586e16427694996d81ce4d54812c5f0"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\services\\notification_message.py": {
"mtime": 1778710280.6376143,
"hash": "514ad0558f51c114a96e8316cd4392bf"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\services\\posts.py": {
"mtime": 1778710280.63862,
"hash": "56792826d430eaa6cdd86796ddb43c10"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\services\\post_suggestions.py": {
"mtime": 1778710280.63862,
"hash": "4a62a36d881bf55a4f73b623b95738bf"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\services\\reference.py": {
"mtime": 1778710280.639125,
"hash": "e86f9864edb3e0eaa1a5e00cd2b903a9"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\services\\sieges.py": {
"mtime": 1778710280.639125,
"hash": "4f43c0760d92d03cc1062ba4b7610dba"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\services\\siege_members.py": {
"mtime": 1778710280.639125,
"hash": "444d8aba42f567d23a8b1a5a12e51200"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\services\\validation.py": {
"mtime": 1778710280.639125,
"hash": "bf8431f5d8b0c8dc793ed927f6de075f"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\app\\services\\__init__.py": {
"mtime": 1778710280.6335557,
"hash": "d41d8cd98f00b204e9800998ecf8427e"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\scripts\\seed.py": {
"mtime": 1778710280.640529,
"hash": "08609621e397256df55a763eb98530c3"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\scripts\\seed_demo.py": {
"mtime": 1778710280.6415303,
"hash": "ef5c21e671c3184b5cbb2240979c0690"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\bot\\app\\config.py": {
"mtime": 1778710280.65144,
"hash": "b80130299a391da986cfd02386e5dea7"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\bot\\app\\discord_client.py": {
"mtime": 1778710280.65144,
"hash": "99db4ab6cf0ecc3d30602e2b8db66a70"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\bot\\app\\http_api.py": {
"mtime": 1778710280.65144,
"hash": "936ed9c6f1e4443f5035d0de3340329e"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\bot\\app\\main.py": {
"mtime": 1778710280.6519608,
"hash": "e05678b35f14c576d1cd2ee7f0ee86b0"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\bot\\app\\telemetry.py": {
"mtime": 1778710280.6519608,
"hash": "a42e02bf2fddd81cca77baa570cdc1ac"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\bot\\app\\__init__.py": {
"mtime": 1778710280.650921,
"hash": "d41d8cd98f00b204e9800998ecf8427e"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\eslint.config.js": {
"mtime": 1778710280.6638145,
"hash": "820d67ddf4af94ab7a60b247ef568493"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\playwright.config.ts": {
"mtime": 1778710280.6663249,
"hash": "c0c6f46da1f83e4dad062bf96a1645ce"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\postcss.config.js": {
"mtime": 1778710280.6663249,
"hash": "33fad9c02cb0ec6d6030369ef6347d57"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\tailwind.config.ts": {
"mtime": 1778710280.6950474,
"hash": "ab2458852a94f3918fc4dc8eec8ee34a"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\vite.config.ts": {
"mtime": 1778710280.6955535,
"hash": "f0b8bf87fac76c40d6423f702e2a122d"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\vitest.config.ts": {
"mtime": 1778710280.6955535,
"hash": "e102be79d7bf6fd8b83320963d3d4d00"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\e2e\\board.spec.ts": {
"mtime": 1778710280.6618135,
"hash": "2e1ab122df18ca111301f5244c1b4903"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\e2e\\members.spec.ts": {
"mtime": 1778710280.6618135,
"hash": "012b10ee19afe7952752bdb34d947596"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\e2e\\siege-lifecycle.spec.ts": {
"mtime": 1778710280.6638145,
"hash": "d3c27ac7e90b3bb5f190694f8d692f6c"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\e2e\\smoke.spec.ts": {
"mtime": 1778710280.6638145,
"hash": "7ffc073a7b7ce29603e7b1dda85b101b"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\App.tsx": {
"mtime": 1778710280.6731784,
"hash": "dc94be0210c5307affde3c5e0e5412b7"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\main.tsx": {
"mtime": 1778710280.6834679,
"hash": "5310a6bf9e3bdf98dc615af3ceff1537"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\vite-env.d.ts": {
"mtime": 1778710280.6950474,
"hash": "0352474ba2918efe13895edbc3780d94"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\api\\board.ts": {
"mtime": 1778710280.6731784,
"hash": "997fae78645cd70b5c2fc3476313e4c1"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\api\\changelog.ts": {
"mtime": 1778710280.6731784,
"hash": "9baa9e3d2be3e4bb566ba86923829a17"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\api\\client.ts": {
"mtime": 1778710280.6746829,
"hash": "10a76391bc7690246d448e867cf7af57"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\api\\config.ts": {
"mtime": 1778710280.6746829,
"hash": "3715d4f6dd51e505949f4b0f7ec9b309"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\api\\members.ts": {
"mtime": 1778710280.6752062,
"hash": "385a652bab3624eb1a556666b369c7be"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\api\\notifications.ts": {
"mtime": 1778710280.6752062,
"hash": "b202ca64e4f5445d309fa8cede22ff0c"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\api\\posts.ts": {
"mtime": 1778710280.6752062,
"hash": "42847a5a2b91ef16e25b1be64c9c5955"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\api\\sieges.ts": {
"mtime": 1778710280.6752062,
"hash": "f1014577b76ed9125141f290e8fb7578"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\api\\types.ts": {
"mtime": 1778710280.6752062,
"hash": "f83637e41fcfc597e14c140b81e74a63"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\api\\version.ts": {
"mtime": 1778710280.6762116,
"hash": "3c320e1ae650ccfaf0fcc58db6f0ad8c"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\components\\Carousel.tsx": {
"mtime": 1778710280.6772118,
"hash": "9c1e5964f8b5e400f963606ee0cd4eb9"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\components\\ChangelogDropdown.tsx": {
"mtime": 1778710280.6772118,
"hash": "32af80944e867e66ec8cf25f6391e233"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\components\\DiscordSyncModal.tsx": {
"mtime": 1778710280.6772118,
"hash": "52ea2cf5bf019ad4e9c376a447e87eaa"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\components\\GroupByToggle.tsx": {
"mtime": 1778710280.6772118,
"hash": "78856592b8aaeb706087c4ef1e6c843b"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\components\\Layout.tsx": {
"mtime": 1778710280.6772118,
"hash": "e813042f31449a0de61f906090164004"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\components\\PostsTab.tsx": {
"mtime": 1778710280.678212,
"hash": "3f11fa6d290cff08dffcc9262a092b3a"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\components\\PostSuggestionsModal.tsx": {
"mtime": 1778710280.678212,
"hash": "9c16b7f40b7352b2f423f7ce46a68b11"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\components\\RequireAuth.tsx": {
"mtime": 1778710280.678212,
"hash": "cd2b2e1cd2d319fc3f3977f7589f291e"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\components\\SiegeLayout.tsx": {
"mtime": 1778710280.679212,
"hash": "5dc89034188b6823763f9c6852f5f03a"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\components\\ui\\badge.tsx": {
"mtime": 1778710280.679212,
"hash": "639942830535b4f2bb8e21e8d3a674e4"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\components\\ui\\button.tsx": {
"mtime": 1778710280.679212,
"hash": "99376e90207bb72645519879a6ad87aa"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\components\\ui\\checkbox.tsx": {
"mtime": 1778710280.679212,
"hash": "596afb4c85e5b432c24e2606e9623bf8"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\components\\ui\\dialog.tsx": {
"mtime": 1778710280.679212,
"hash": "b917e9be88d5dc6b1b6d2660df3be9a0"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\components\\ui\\dropdown-menu.tsx": {
"mtime": 1778710280.6804683,
"hash": "8f8f3621f203e9d7d566ed3827ddb95c"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\components\\ui\\input.tsx": {
"mtime": 1778710280.6804683,
"hash": "4f418a1677a7fa837b7a5f16b05eabea"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\components\\ui\\label.tsx": {
"mtime": 1778710280.6804683,
"hash": "ede7445a0bd4c9380bff1fb664d21763"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\components\\ui\\select.tsx": {
"mtime": 1778710280.6804683,
"hash": "594f45397eb2ac6bd77df7b7e37d5644"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\components\\ui\\table.tsx": {
"mtime": 1778710280.681468,
"hash": "0e1676ab2a771ea388b5fa63036cd502"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\components\\ui\\textarea.tsx": {
"mtime": 1778710280.681468,
"hash": "4118508b3f819ceaee3b0d5f16bbb649"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\context\\AuthContext.tsx": {
"mtime": 1778710280.681468,
"hash": "44ab8c9079dffb96a8f0826540377cb3"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\lib\\buildingColors.ts": {
"mtime": 1778710280.6824672,
"hash": "b348eff15681381b572787a373b909ce"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\lib\\groupPostConditions.ts": {
"mtime": 1778710280.6824672,
"hash": "788b0f8427b263370cdab41d8850cf41"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\lib\\post-priority.ts": {
"mtime": 1778710280.6824672,
"hash": "94e7a97549b23802f43bb3f6ac6c28cc"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\lib\\postConditionTypes.ts": {
"mtime": 1778710280.6834679,
"hash": "3b06353374f1df46ea8de1cfd4afd788"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\lib\\useGroupByPreference.ts": {
"mtime": 1778710280.6834679,
"hash": "bb6b5032d31d41e56bfa0c1462240482"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\lib\\utils.ts": {
"mtime": 1778710280.6834679,
"hash": "d9837f38cc05303254571985e3164050"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\pages\\BoardPage.tsx": {
"mtime": 1778710280.6834679,
"hash": "ca60bdc402bf7fc73d45bf4a9786efa2"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\pages\\ComparisonPage.tsx": {
"mtime": 1778710280.6849875,
"hash": "5f40cf11f1c285fcc713c66f6b70cc7e"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\pages\\LandingPage.tsx": {
"mtime": 1778710280.6849875,
"hash": "0592d360b4d150e643f2ed7d853cec37"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\pages\\LoginPage.tsx": {
"mtime": 1778710280.6849875,
"hash": "a7f86666a5e860fa06370cd44d5b2009"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\pages\\MemberDetailPage.tsx": {
"mtime": 1778710280.6849875,
"hash": "91d2961273fc9f2065dd82b95a4dd2e6"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\pages\\MembersPage.tsx": {
"mtime": 1778710280.6860092,
"hash": "0e20169e021eddba33936ff03cb09ed6"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\pages\\PostPrioritiesPage.tsx": {
"mtime": 1778710280.6860092,
"hash": "44ba6c946c49e4491f401a05ada7b0ce"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\pages\\PostsPage.tsx": {
"mtime": 1778710280.6860092,
"hash": "6299292c6d99e49321c62ebd458b5a3f"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\pages\\SiegeCreatePage.tsx": {
"mtime": 1778710280.6860092,
"hash": "2889e8903df72e1ab56a1a1a13ef0519"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\pages\\SiegeMembersPage.tsx": {
"mtime": 1778710280.687007,
"hash": "864268a2bc137e9b39782eb85260adff"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\pages\\SiegeSettingsPage.tsx": {
"mtime": 1778710280.687007,
"hash": "f594078ade4735208a55056c7cf4dd5f"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\pages\\SiegesPage.tsx": {
"mtime": 1778710280.687007,
"hash": "f93156052c5124138148122147b74acb"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\pages\\SystemPage.tsx": {
"mtime": 1778710280.687007,
"hash": "9332c96da0f1502dbb14d6f1d7164aaa"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\src\\types\\changelog.d.ts": {
"mtime": 1778710280.6940484,
"hash": "29f6e6e4d1a48ca3686c20d21c03dc3c"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\scripts\\bootstrap-db.ps1": {
"mtime": 1778710280.7000616,
"hash": "2963ef492dbaa1e8aed3c7d0b42cb2bf"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\scripts\\bootstrap-excel-import.ps1": {
"mtime": 1778710280.7010694,
"hash": "833c292e832a70a4d642e969418cec01"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\scripts\\bootstrap-images.ps1": {
"mtime": 1778710280.701412,
"hash": "770e3450dec21a6498dd9380f2070049"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\scripts\\bootstrap-keyvault.ps1": {
"mtime": 1778710280.701412,
"hash": "571c851084af0db873bdc82226b59797"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\scripts\\bootstrap-reimport.ps1": {
"mtime": 1778710280.701412,
"hash": "39d7a16633e94d6cefeb8aca40862cff"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\scripts\\generate-origin-pfx.ps1": {
"mtime": 1778710280.7034204,
"hash": "b0900217644486cdf9adf852befa4fde"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\scripts\\rebuild.ps1": {
"mtime": 1778710280.7034204,
"hash": "1b5123763516e1ee3dbc308f2638eb4f"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\scripts\\excel-import\\import_excel.py": {
"mtime": 1778710280.70243,
"hash": "4151fee1079d2b495340976e008542dd"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\scripts\\excel-import\\tests\\__init__.py": {
"mtime": 1778710280.70243,
"hash": "d41d8cd98f00b204e9800998ecf8427e"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\scripts\\experiments\\run-graphify-dry-run.ps1": {
"mtime": 1778715097.451517,
"hash": "8a66f56768d8c9b2b04c9d03452a8285"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\CHANGELOG.md": {
"mtime": 1778710280.6144302,
"hash": "0c5a48d5f48933acad20d931797847b0"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\CLAUDE.md": {
"mtime": 1778710280.614946,
"hash": "efb936d1d3711ed3ca65b394f9d6b9b2"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\CODE_OF_CONDUCT.md": {
"mtime": 1778710280.614946,
"hash": "9b2d51a163a531cb2f62e72697b0ccc1"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\CONTRIBUTING.md": {
"mtime": 1778710280.614946,
"hash": "f1099f1c0582333df2fabef4dccad223"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\docker-compose.prod.yml": {
"mtime": 1778710280.6545522,
"hash": "e55ffd8443f4dd9cf1acb386a7956bfb"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\docker-compose.yml": {
"mtime": 1778710280.6550682,
"hash": "376b6eb4a3cfab39144103477cea42cf"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\README.md": {
"mtime": 1778710280.615952,
"hash": "8b4ba27465aa3d5dfd16ed64c6cbf45f"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\SUPPORT.md": {
"mtime": 1778710280.615952,
"hash": "64c8848cde6a11b59d25bcc9b621e546"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\requirements-dev.txt": {
"mtime": 1778710280.640529,
"hash": "61ce4838a8959c3c183db9bab83b737d"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\backend\\requirements.txt": {
"mtime": 1778710280.640529,
"hash": "b06051b552c2ea4732940c0dbc2b9db0"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\bot\\requirements-dev.txt": {
"mtime": 1778710280.6524813,
"hash": "cf6fc69a9af8b95f5758cac0a94bb9e6"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\bot\\requirements.txt": {
"mtime": 1778710280.6524813,
"hash": "fbf3dc8cb3581931efa8dc526f44f7ef"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\docs\\IMPLEMENTATION_PLAN.md": {
"mtime": 1778710280.6550682,
"hash": "5e4f9f914ca2ce9d67d6705a5933b7ba"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\docs\\RUNBOOK.md": {
"mtime": 1778710280.6555874,
"hash": "50fc656921246e9004108c9b114a09e5"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\docs\\siege_levels.md": {
"mtime": 1778710280.6587057,
"hash": "07d9f028f42a8b94ce3365a6f72bafc4"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\docs\\WEB_DESIGN_DOCUMENT.md": {
"mtime": 1778710280.656117,
"hash": "83b709cc8ac4aa14b027eda0a0c562b8"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\docs\\design-refs\\post-suggestions\\README.md": {
"mtime": 1778710280.6566384,
"hash": "de10b175d0df9256e5daeca315f7b252"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\docs\\experiments\\graphify-dry-run.md": {
"mtime": 1778711028.4433894,
"hash": "496df0deb7da1e88640f0a8bcdcb7e3b"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\docs\\mockups\\mockup-landing.html": {
"mtime": 1778710280.6571586,
"hash": "0548e8204463ddf92a09c5ce6f97fe34"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\docs\\mockups\\mockup-login.html": {
"mtime": 1778710280.6571586,
"hash": "7e1759c2d6a5fa6a3c4e5ed58777c289"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\docs\\mockups\\README.md": {
"mtime": 1778710280.6566384,
"hash": "fe28480a5cc9c486f4dc5d6be6c5f368"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\docs\\plans\\public-launch-self-hostable-and-landing-page.md": {
"mtime": 1778710280.657677,
"hash": "afed648bab4d1590d9b833607a4f7502"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\docs\\self-host\\anywhere.md": {
"mtime": 1778710280.6581955,
"hash": "2efab5a64706d9964b8fa13de3037449"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\docs\\self-host\\azure.md": {
"mtime": 1778710280.6587057,
"hash": "c9ee5c5fc8721e7c0ca2bb54da0782c9"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\docs\\superpowers\\plans\\2026-04-08-discord-auth-implementation.md": {
"mtime": 1778710280.6592517,
"hash": "01ee8f99120035b952a2699b8a01eb6b"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\docs\\superpowers\\plans\\2026-05-08-component-versioning.md": {
"mtime": 1778710280.6597755,
"hash": "4eea9e7828ef6f2c88737f1f2feb1ee2"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\docs\\superpowers\\plans\\2026-05-09-post-suggestions.md": {
"mtime": 1778710280.6597755,
"hash": "3c89d2df41aebf5c5bc5add19cbd6281"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\docs\\superpowers\\plans\\discord-auth-plan.md": {
"mtime": 1778710280.6597755,
"hash": "bab1c00cda76f8ccaf26079a049ecf40"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\docs\\superpowers\\plans\\v1-release-plan.md": {
"mtime": 1778710280.6607814,
"hash": "f7ebc80091b9fc6eb0a5bf8661c0300e"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\index.html": {
"mtime": 1778710280.6638145,
"hash": "dde055b245027a69a68049238ed823b3"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\graphify-out-with-tests\\graph.html": {
"mtime": 1778718921.8433201,
"hash": "b6226c2e30e0ccfbc56b15297319fa65"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\graphify-out-with-tests\\GRAPH_REPORT.md": {
"mtime": 1778718921.7281322,
"hash": "2c56ab55dda9d94cb5aab4e1a21a2cf1"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\infra\\README.md": {
"mtime": 1778710280.696556,
"hash": "3e76fbd727bcceeb02eb75d416c64aff"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\scripts\\excel-import\\README.md": {
"mtime": 1778710280.701412,
"hash": "4a0e8a05091bd257fe417671858923a2"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\scripts\\excel-import\\requirements.txt": {
"mtime": 1778710280.70243,
"hash": "5e740ca3e2b112ec37fea64eae859ae0"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\wiki\\FAQ.md": {
"mtime": 1778710280.7034204,
"hash": "5e52ba23a226df064a14d75b1fd0d715"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\wiki\\Getting-Started.md": {
"mtime": 1778710280.7034204,
"hash": "f9dea57e10cfeada6f10255144249741"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\wiki\\Home.md": {
"mtime": 1778710280.7034204,
"hash": "32652bdc5aadfc11288cc5a4df5fe4a3"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\wiki\\Self-Host-on-Any-VPS.md": {
"mtime": 1778710280.7034204,
"hash": "178c7e9323276c57b1ce23786431f634"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\wiki\\Self-Host-on-Azure.md": {
"mtime": 1778710280.7049341,
"hash": "170d3ef1fbc3b5d52c18a8b6470951f5"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\wiki\\_Sidebar.md": {
"mtime": 1778710280.7049341,
"hash": "d92afc34965b5e470b581ce61e53b6ca"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\public\\favicon.svg": {
"mtime": 1778710280.6663249,
"hash": "1544a9686a82728b10dd2d54a4c539b4"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\public\\landing\\carousel-assignment-board.png": {
"mtime": 1778710280.6673253,
"hash": "138b785969e45c8eeec46b97c86dbfec"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\public\\landing\\carousel-discord-image.png": {
"mtime": 1778710280.6673253,
"hash": "490ecc84ff80e40ca12651e2626bc424"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\public\\landing\\carousel-member-management.png": {
"mtime": 1778710280.6688316,
"hash": "e87aa520a2aaecf3e9a1eea306182d0d"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\public\\landing\\carousel-post-assignments.png": {
"mtime": 1778710280.6698372,
"hash": "79bdc954a2b7803d178cc4b3f2d7fbd8"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\public\\landing\\carousel-siege-comparison.png": {
"mtime": 1778710280.6711512,
"hash": "913d494ae2e7465514441dec70f864c9"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\public\\landing\\carousel-validation-errors.png": {
"mtime": 1778710280.6721778,
"hash": "a6f43ec1ae7d66d5580b8b8d9d8c154e"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\public\\landing\\hero-board.png": {
"mtime": 1778710280.6721778,
"hash": "4640413678efc867d27bceed64b60ea9"
},
"I:\\games\\raid\\siege-web\\.worktrees\\experiment-graphify-dry-run-doc\\frontend\\public\\landing\\og-image.png": {
"mtime": 1778710280.6731784,
"hash": "4640413678efc867d27bceed64b60ea9"
}
}
-194
View File
@@ -1,194 +0,0 @@
# Graphify Dry-Run — Results & Decision
**Date:** 2026-05-15
**Tool:** [`safishamsi/graphify`](https://github.com/safishamsi/graphify) (PyPI `graphifyy`)
**Tracking issue:** #397
**Runbook:** [`runbook.md`](./runbook.md)
**Source codebase:** [`glitchwerks/rsl-siege-manager`](https://github.com/glitchwerks/rsl-siege-manager) @ `6085fd66`
**Decision:** Do not adopt.
---
## TL;DR
The dry-run was executed twice against rsl-siege-manager at commit `6085fd66` — once excluding tests, once including them. Evaluated against the acid-test criteria from #397 (god nodes, surprising connections, and suggested questions should reflect things the user would nominate themselves), the tool failed on all three headline outputs. The without-tests run surfaces utilities and React page components alongside legitimate domain models; the with-tests run is dominated by test fixtures. Neither output justifies integrating a `PreToolUse` hook.
---
## What was run
Two runs at commit `6085fd66`:
| Run | Scope | Nodes | Edges | Communities | Extraction quality |
|-----|-------|-------|-------|-------------|-------------------|
| A (codebase only) | `.graphifyignore` excluded `backend/tests/`, `frontend/src/**/__tests__/` | 833 | 1758 | 52 | 85% EXTRACTED / 15% INFERRED (avg confidence 0.59) |
| B (codebase + tests) | No exclusions beyond vendored deps | 1886 | 3876 | 141 | 90% EXTRACTED / 10% INFERRED (avg confidence 0.62) |
Run cost: $0 token cost in both cases. graphify uses tree-sitter for code extraction; LLM API calls fire only for non-code files. After `.graphifyignore`, there were effectively none.
---
## Evaluation against the acid test
Issue #397 set this bar:
> "whether GRAPH_REPORT.md's named extractions (god nodes, surprising connections, suggested questions) reflect things the user would nominate themselves — generic graph-theory output ('`index.ts` is highly connected') means it didn't work."
Each finding below quotes the report directly. The raw artifacts are not committed (see "Artifact handling"), but the quotes are verifiable by re-running the dry-run against the same commit.
### Finding 1 — Test fixtures dominate "core abstractions" with tests included
Run B's god-node list, verbatim (`graphify-out-with-tests/GRAPH_REPORT.md`, lines 141150):
```
1. `_make_siege()` - 124 edges
2. `_make_member()` - 92 edges
3. `_make_position()` - 85 edges
4. `SiegeMember` - 78 edges
5. `_make_building()` - 64 edges
6. `_make_group()` - 60 edges
7. `BoardPage()` - 55 edges
8. `makeSiegeMember()` - 55 edges
9. `PostsPage()` - 37 edges
10. `_session_with_siege_and_configs()` - 35 edges
```
Six of the top ten — positions 1, 2, 3, 5, 6, and 8 — are test factory functions (`_make_siege`, `_make_member`, `_make_position`, `_make_building`, `_make_group`, `makeSiegeMember`). Position 10 is a test session fixture. These are the highest-connectivity nodes in the graph, and they are infrastructure for verifying the codebase, not the codebase itself.
This is the cleanest failure signal in the dataset. The god-node list is explicitly labeled "your core abstractions." No developer would nominate `_make_siege()` as a core abstraction of a siege-assignment web app. The metric — degree centrality — is measuring test coverage, not architecture. The inversion is structural: the better your test coverage, the more your test factories saturate every part of the codebase, and the higher their degree count climbs. Codebases that most need architectural insight (low coverage, high complexity) will produce the cleanest god-node lists. Codebases that least need it (high coverage, known domain) will look like run B.
### Finding 2 — Codebase-only god nodes are surface-level
Run A's god-node list, verbatim (`graphify-out/GRAPH_REPORT.md`, lines 5564):
```
1. `SiegeMember` - 55 edges
2. `BoardPage()` - 53 edges
3. `Post Suggestions Modal Handoff` - 40 edges
4. `postsTab` - 29 edges
5. `cn()` - 29 edges
6. `PostsPage()` - 28 edges
7. `BuildingType` - 27 edges
8. `MembersPage()` - 27 edges
9. `MemberRole` - 25 edges
10. `Self-Host on Azure Wiki Page` - 23 edges
```
`SiegeMember`, `BuildingType`, and `MemberRole` at positions 1, 7, and 9 are legitimate domain models a developer would identify as important. That is three of ten.
The remaining seven are less useful. `BoardPage()`, `PostsPage()`, and `MembersPage()` at positions 2, 6, and 8 are React top-level page components — they import many things because they are entry points, not because they encode domain logic. `cn()` at position 5 is a one-line Tailwind class-merging utility (`src/lib/utils.ts`). It scores 29 edges because every component that merges conditional classes imports it. This is the canonical generic-graph-theory false positive the runbook warned about: `cn()` is "highly connected" in the same way `/dev/null` would be if files wrote to it — the connection count reflects a structural pattern, not semantic importance. `Post Suggestions Modal Handoff` at position 3 is a planning document node extracted from `docs/design-refs/`, not a code entity at all. `Self-Host on Azure Wiki Page` at position 10 is a wiki article.
The acid test asks whether these are things the user would nominate. They are not.
### Finding 3 — Surprising connections cross language boundaries spuriously
Both runs surface INFERRED edges between Python backend types and TypeScript frontend types, presented under the heading "Surprising Connections (you probably didn't know these)." From run A (`graphify-out/GRAPH_REPORT.md`, lines 7374):
```
- `AuthError` --uses--> `Member` [INFERRED]
backend/app/api/auth.py → frontend/src/api/types.ts
```
And from run B (`graphify-out-with-tests/GRAPH_REPORT.md`, lines 158159):
```
- `TestStartupValidation` --uses--> `MemberRole` [INFERRED]
backend/tests/test_auth.py → frontend/src/api/types.ts
```
A Python class does not "use" a TypeScript type at runtime. These are name-based similarity matches — `AuthError` and `Member` share a namespace with identically-named constructs in the frontend — presented as semantic relationships. The confidence is low (avg INFERRED confidence 0.59 in run A, 0.62 in run B), but the framing ("you probably didn't know these") presents them as insights worth investigating. They are not.
The one genuinely plausible INFERRED connection in run A is:
```
- `PostPriorityResponse` --uses--> `PostPriorityConfig` [INFERRED]
backend/app/api/post_priority_config.py → frontend/src/api/posts.ts
```
The backend schema and the frontend type do mirror each other by contract. But that relationship is a deliberate design decision well-known to anyone who wrote it — not a discovery.
### Finding 4 — Community cohesion is universally weak
The majority of rsl-siege-manager's 52 communities (run A) score between 0.05 and 0.17 on cohesion. Run A community distribution:
- Communities 0, 2, 3, 6: cohesion 0.050.06 (the four largest communities, 36112 nodes each)
- Most remaining communities: cohesion 0.080.17
- Cohesion above 0.25: six communities, all small (310 nodes)
The report itself flags cohesion 0.05 as "weakly interconnected" in the Suggested Questions section: "Should `Community 0` be split into smaller, more focused modules? — Cohesion score 0.05 - nodes in this community are weakly interconnected." Community 0 has 112 nodes.
rsl-siege-manager has a clean three-service architecture (backend / frontend / bot) that any developer can describe in a sentence. The graph algorithm is not finding that structure — it is producing communities with no legible semantic identity and flagging most of them as internally incoherent.
### Finding 5 — Noise inflated into knowledge gaps
Run A reports 259 isolated nodes; run B reports 752. The leading examples in both are identical (`graphify-out/GRAPH_REPORT.md`, line 213; `graphify-out-with-tests/GRAPH_REPORT.md`, line 447):
```
`initial schema Revision ID: 0001 Revises: Create Date: 2026-03-16`,
`add autofill and attack day preview columns to siege Revision ID: 0002 Revises:`,
`make siege date nullable Revision ID: 0003 Revises: 0002 Create Date: 2026-03-1`,
`Add post_priority_config table`, ...
```
These are Alembic migration revision docstrings parsed as standalone graph nodes. A migration docstring like `"make siege date nullable"` is a change-tracking annotation, not an architectural entity. There are 17 Alembic migration files in this repo. The isolated-node count growing from 259 to 752 when tests are added is almost entirely test docstrings and test function descriptions parsed the same way.
The report labels these as "possible documentation gaps or missing edges" — a framing that implies they are meaningful silences the developer should investigate. They are not gaps; they are noise.
### Finding 6 — Suggested questions are self-referential
The Suggested Questions section in both runs consists primarily of two kinds of questions:
1. **Betweenness centrality prompts:** "Why does `_make_siege()` connect Community 12 to Community 0, Community 1, Community 3...?" These ask the developer to explain why a test fixture has high betweenness. The answer is obvious: it creates the primary domain object; every test uses it.
2. **Inferred-edge audits:** "Are the 17 inferred relationships involving `SiegeMember` (e.g. with `Base` and `TestSeedDemoMembers`) actually correct?" This is the tool asking the developer to validate the tool's own low-confidence connections. It is not the tool answering questions about the codebase; it is the tool outsourcing its uncertainty.
Run A's most interesting question — "What is the exact relationship between `bootstrap-images.ps1` and `scripts/bootstrap-images.ps1`?" — is itself tagged AMBIGUOUS. The answer is: they are the same script referenced by two slightly different paths in different contexts. This is a file-naming question, not an architectural one.
---
## What graphify is good at
The throughput is fine: 833 nodes in a few minutes, $0 LLM cost on a code-heavy repo. The tree-sitter extraction is genuinely fast and does pick up real entities — `SiegeMember`, `BuildingType`, and `MemberRole` in the god-node list are correct. The `graph.html` interactive visualization is well-built and easy to navigate. The EXTRACTED cross-service connections are occasionally real: `PostPriorityResponse --uses--> PostPriorityConfig` between `backend/app/api/post_priority_config.py` and `frontend/src/api/posts.ts` reflects an actual contract.
The problem is not the underlying graph build. The problem is what the report does with it.
---
## Why this is a rejection, not a tuning problem
The headline outputs — god nodes, surprising connections, suggested questions — are what would justify wiring a `PreToolUse` hook that nudges the assistant to consult `GRAPH_REPORT.md` on every `grep`/`rg`/`find` invocation. If those outputs are mostly test fixtures (run B), surface-level import counts (run A), low-confidence cross-language inferences, and self-referential audit requests, then the hook would be steering the assistant's attention toward noise on every search. Tightening `.graphifyignore` further would fix run B's test-fixture problem, but it would not fix the architecture-of-the-metric problem visible in run A: degree centrality will always surface utilities and entry points over domain logic, regardless of what the ignore file excludes. The tool is measuring the right thing (connectivity) for the wrong purpose (identifying abstractions worth knowing about).
---
## Cost incurred vs cost avoided
**Cost incurred:**
- ~10 minutes of CLI time across two runs.
- $0 LLM cost (tree-sitter handled all code; no non-code files survived the ignore filter in any meaningful quantity).
**Cost avoided by not adopting:**
The two harness mutations from `graphify claude install` documented in #397:
1. **Global CLAUDE.md append** — a `# graphify` block appended to `~/.claude/CLAUDE.md` without a parseable fence marker, requiring manual cleanup on backout.
2. **Per-project `PreToolUse` hook** — fires on `Bash` commands containing `grep`/`rg`/`find` substrings. As noted in the runbook's Windows-specific gotchas section: the hook matcher is substring-based (`*grep*`), creating false-positive nudges on `pg_dump | grep`, `kubectl get pods | grep`, and similar. The hook also uses `python3` (not `python.exe`) which may silently no-op on Windows.
---
## Artifact handling
The raw outputs from both runs — `graph.html`, `graph.json`, `GRAPH_REPORT.md`, `cache/`, `manifest.json` (approximately 12 MB total) — are committed alongside this writeup under [`./graphify-out/`](./graphify-out/) and [`./graphify-out-with-tests/`](./graphify-out-with-tests/). The quoted findings above are auditable against the originals; the interactive `graph.html` files render the underlying force-directed graph if you want to explore.
Reproducing the run against a different revision: see [`runbook.md`](./runbook.md) for the methodology and acid-test criteria.
---
## Follow-up
- Issue tracking is disabled on this fork, so the PR that lands this evaluation is the durable record of the decision.
- No upstream contribution intended — this is an evaluation of graphify as a consumer, not a change request to the tool. The fork exists as a stable point to reference if upstream evolves.
---
🤖 _Generated by Claude Code on behalf of @cbeaulieu-gt_
-160
View File
@@ -1,160 +0,0 @@
# Graphify Dry-Run for rsl-siege-manager
> **Captured artifact.** This is the runbook as used during the [rsl-siege-manager evaluation](./results.md). Originally lived at `docs/experiments/graphify-dry-run.md` in that repo; relocated here so methodology and results stay together. References to siege-web-specific paths and cleanup commands are kept verbatim — they reflect the original context.
A scoped evaluation plan for [`safishamsi/graphify`](https://github.com/safishamsi/graphify) — a tool that builds a queryable knowledge graph (code + docs + PDFs + images) from a project folder and exposes it to AI coding assistants.
**Goal of this dry-run:** produce graphify's artifacts inside `rsl-siege-manager/graphify-out/` so I can judge whether the graph genuinely illuminates this codebase, **without** modifying my global `~/.claude/CLAUDE.md`, this repo's `.claude/settings.json`, or installing any harness hooks. Everything below is reversible by deleting one folder.
---
## Why this approach
Graphify's full install does two things:
1. **Global**: drops a skill at `~/.claude/skills/graphify/SKILL.md` and **appends a `# graphify` block to `~/.claude/CLAUDE.md`** (string-match guarded — not a fenced/marker block, so manual cleanup is needed if I back it out).
2. **Per-project**: appends a `## graphify` section to this repo's `CLAUDE.md` and registers a `PreToolUse` hook in `.claude/settings.json` that nudges the assistant to consult `GRAPH_REPORT.md` whenever a `Bash` command contains `grep`/`rg`/`find`/etc.
Both are reasonable but non-trivial mutations to harness configuration I tune carefully. The dry-run skips both, runs only the CLI, and lets me decide whether the artifact is worth the integration cost **after** seeing it.
---
## Step 1 — Install the CLI globally
```powershell
uv tool install graphifyy
```
> The PyPI package is `graphifyy` (double-y). The CLI command is `graphify`.
Verify it's on PATH:
```powershell
graphify --version
```
If "not recognized," open a new PowerShell window — `uv tool` updates PATH but the current session won't see it.
---
## Step 2 — Optional: gate the first build with `.graphifyignore`
Cheap insurance. Each non-code file (markdown, PDF, image) becomes an LLM API call during the first build. A `.graphifyignore` (same syntax as `.gitignore`, including `!` negation) keeps vendored deps and build output out of scope.
From the rsl-siege-manager root:
```powershell
@'
node_modules/
dist/
build/
.next/
.venv/
coverage/
*.generated.*
*.min.js
'@ | Set-Content -Encoding UTF8 .graphifyignore
```
Adjust to rsl-siege-manager's actual layout. If unsure what to ignore, skip this step — the build will still work, just bigger.
---
## Step 3 — Build the graph (the only step with $ cost)
From the rsl-siege-manager root:
```powershell
graphify extract .
```
> **Estimated cost:** `$0.10$2.00` depending on the number of docs, PDFs, and images that survive the ignore filter. Watch terminal output; `Ctrl+C` is safe at any point.
What happens under the hood:
| Content type | Mechanism | Cost |
| --- | --- | --- |
| Code (29 languages, AST via tree-sitter) | Local | Free |
| Docs, markdown, PDFs, images, videos | LLM API call per file | $$ |
Watch terminal output. If it's processing far more files than expected, `Ctrl+C` and tighten `.graphifyignore` before re-running.
Check the cost summary when it finishes:
```powershell
Get-Content .\graphify-out\cost.json
```
---
## Step 4 — Inspect the three artifacts
```powershell
# The headline summary the assistant would read on every query
code .\graphify-out\GRAPH_REPORT.md
# The interactive graph (click nodes, filter, search)
Start-Process .\graphify-out\graph.html
# The raw graph data (used by the query commands below)
Get-Content .\graphify-out\graph.json | Select-Object -First 50
```
**The honest evaluation lives in `GRAPH_REPORT.md`, not `graph.html`.** The viz is dopamine — colorful and clickable on any codebase. The report's "god nodes," "surprising connections," and "suggested questions" sections are what tell me whether the LLM extraction actually *understood* rsl-siege-manager. If those sections name files/concepts I'd nominate myself, it worked. If they're generic ("`index.ts` is highly connected") or wrong, it didn't.
---
## Step 5 — Try query commands without any hook wiring
These work directly off `graphify-out/graph.json` — no skill registration, no settings.json mutation:
```powershell
graphify query "how does authentication flow through the app?"
graphify query "what connects the database layer to the API routes?"
graphify path "<some-component-name>" "<some-service-name>"
graphify explain "<a-concept-i-want-mapped>"
```
**Acid test:** ask 35 questions I already know the answer to. If it answers them correctly, the tool can help with the ones I don't.
---
## Step 6 — Decide
| Outcome | Next move |
| --- | --- |
| Graph is genuinely illuminating | Run `graphify claude install` (accept the CLAUDE.md / `.claude/settings.json` mutations) |
| Useful but not always-on | Keep the CLI, rebuild manually when useful, query from terminal — no install |
| Generic or wrong | Delete and move on |
---
## Abort / full cleanup
Nothing outside `rsl-siege-manager/graphify-out/` was touched. To roll back completely:
```powershell
Remove-Item -Recurse -Force .\graphify-out
Remove-Item .\.graphifyignore # if added and unwanted
Remove-Item .\docs\experiments\graphify-dry-run.md # this file
uv tool uninstall graphifyy # remove the CLI itself
```
After this, the repo is byte-identical to before the dry-run, and `~/.claude/CLAUDE.md` was never modified.
---
## Windows-specific gotchas to watch for
- **`/graphify extract .` will fail in PowerShell.** PowerShell treats `/` as a path separator. Use `graphify extract .` (no leading slash). The slash form only works inside an AI coding assistant's chat prompt.
- **The PreToolUse hook graphify installs uses `python3`.** Windows installers typically register `python.exe`, not `python3.exe`. If I do eventually run `graphify claude install`, the hook's `python3 -c "..."` may silently no-op (it's wrapped in `2>/dev/null || true`) — meaning the nudge never fires and I won't know.
- **The hook also relies on Bash `case` syntax.** Claude Code on Windows routes hook commands through Git Bash, so this works — but it's an implicit dependency on Git Bash being present.
- **Hook matcher is substring-based on `*grep*`.** That catches `pg_dump | grep`, `kubectl get pods | grep`, anything-grep. False-positive nudges are low cost but worth knowing.
---
## Reference
- Repo: https://github.com/safishamsi/graphify
- PyPI: https://pypi.org/project/graphifyy/
- Repo signals at evaluation time (2026-05-13): 47k stars, 5k forks, MIT, ~5 weeks old. Star count is anomalously high for age — treat it as marketing signal, not quality signal. Evaluate the artifact, not the badges.
+88
View File
@@ -0,0 +1,88 @@
# Case Study: rsl-siege-manager (Python + TypeScript monorepo)
A graphify dry-run against [`glitchwerks/rsl-siege-manager`](https://github.com/glitchwerks/rsl-siege-manager) — a real-world web app with a Python (FastAPI) backend, a TypeScript (React + Vite) frontend, and a Python Discord bot, all in one repo. Captured here as a worked example of running graphify on a mixed-language full-stack codebase that includes a substantial test suite.
**Corpus:** `glitchwerks/rsl-siege-manager` @ commit `6085fd66`
**Date:** 2026-05-15
**Findings:** [`review.md`](./review.md)
**Raw artifacts:** [`GRAPH_REPORT.md`](./GRAPH_REPORT.md), [`graph.html`](./graph.html), [`graph.json`](./graph.json), [`manifest.json`](./manifest.json)
## How to reproduce
### 1. Clone the corpus
```bash
git clone https://github.com/glitchwerks/rsl-siege-manager
cd rsl-siege-manager
git checkout 6085fd66
```
### 2. Install the CLI
```powershell
uv tool install graphifyy
```
> The PyPI package is `graphifyy` (double-y). The CLI command is `graphify`.
Verify it's on PATH:
```powershell
graphify --version
```
If "not recognized" on Windows, open a new shell — `uv tool` updates PATH but the current session won't see it.
### 3. Run extraction
This case study ran extraction with no `.graphifyignore` (the run included tests). To reproduce a tests-included run:
```powershell
graphify extract .
```
Watch terminal output. graphify uses tree-sitter for code (free, fast) and LLM API calls only for non-code files (markdown, PDFs, images). On a code-heavy repo like rsl-siege-manager, the cost is dominated by docs.
Check the cost summary when it finishes:
```powershell
Get-Content .\graphify-out\cost.json
```
### 4. Inspect
```powershell
# The headline summary an assistant would read
code .\graphify-out\GRAPH_REPORT.md
# The interactive graph
Start-Process .\graphify-out\graph.html
```
## What's in this directory
| File | What it is |
|---|---|
| `README.md` | This file — corpus description + reproduction steps |
| `review.md` | Findings against the headline outputs in `GRAPH_REPORT.md` |
| `GRAPH_REPORT.md` | Raw graphify report (god nodes, communities, surprising connections, suggested questions) |
| `graph.html` | Interactive force-directed visualization |
| `graph.json` | Underlying graph data used by `graphify query` |
| `manifest.json` | Per-file extraction record |
The AST cache (`graphify-out/cache/`) is regenerable and not committed.
## Why this corpus
rsl-siege-manager is structurally interesting for graphify evaluation because:
- **Three services in one repo** — Python backend, TypeScript frontend, Python bot — exercises cross-language inference.
- **Substantial test suite** — both Python (`backend/tests/`) and TypeScript (`frontend/src/**/__tests__/`) — surfaces how degree-centrality behaves on covered codebases.
- **17 Alembic migrations** with revision docstrings — exercises how docstring-shaped content is or is not treated as graph entities.
- **Clean three-tier architecture** — a developer can describe the structure in one sentence, giving a clear ground truth to evaluate community detection against.
## Reference
- graphify repo: https://github.com/safishamsi/graphify
- graphify PyPI: https://pypi.org/project/graphifyy/
- rsl-siege-manager: https://github.com/glitchwerks/rsl-siege-manager
+154
View File
@@ -0,0 +1,154 @@
# Review: rsl-siege-manager
**Corpus:** [`glitchwerks/rsl-siege-manager`](https://github.com/glitchwerks/rsl-siege-manager) @ `6085fd66`
**Date:** 2026-05-15
**Run:** tests included, no `.graphifyignore`
**Counts:** 1886 nodes · 3876 edges · 141 communities · 90% EXTRACTED / 10% INFERRED (avg INFERRED confidence 0.62)
**Cost:** $0 (tree-sitter only; this corpus's natural file mix surfaced no non-code files in meaningful quantity)
**Setup:** ~10 minutes of CLI time end-to-end
This review evaluates the **headline outputs** in `GRAPH_REPORT.md` — god nodes, surprising connections, communities, isolated nodes, suggested questions — against a single criterion: do they reflect things a developer familiar with this codebase would themselves nominate as core, surprising, or worth investigating? Each finding quotes the report directly so it is verifiable against the committed artifacts.
---
## Finding 1 — Test fixtures dominate "core abstractions" when tests are included
Top god nodes, verbatim from `GRAPH_REPORT.md` (lines 141150):
```
1. `_make_siege()` - 124 edges
2. `_make_member()` - 92 edges
3. `_make_position()` - 85 edges
4. `SiegeMember` - 78 edges
5. `_make_building()` - 64 edges
6. `_make_group()` - 60 edges
7. `BoardPage()` - 55 edges
8. `makeSiegeMember()` - 55 edges
9. `PostsPage()` - 37 edges
10. `_session_with_siege_and_configs()` - 35 edges
```
Six of the top ten — positions 1, 2, 3, 5, 6, and 8 — are test factory functions (`_make_siege`, `_make_member`, `_make_position`, `_make_building`, `_make_group`, `makeSiegeMember`). Position 10 is a test session fixture. These are the highest-connectivity nodes in the graph, and they are infrastructure for verifying the codebase, not the codebase itself.
The god-node list is labeled "your core abstractions" in the report. On this corpus, no developer would nominate `_make_siege()` as a core abstraction of a siege-assignment web app. Degree centrality on a well-tested codebase will tend to surface test factories: by design, factories create the primary domain objects that every test then exercises, so they accumulate edges from every part of the suite. The pattern is structural — the better the test coverage, the more saturated the factory's degree count.
For users running graphify on a codebase with substantial test coverage, the documented mitigation (a `.graphifyignore` excluding `tests/`, `__tests__/`, etc.) is effective at removing this class of false-positive. See Finding 2 for what the same corpus surfaces without tests.
## Finding 2 — Without tests, god nodes mix domain types with entry points and utilities
For comparison, an earlier run of the same corpus with `.graphifyignore` excluding `backend/tests/` and `frontend/src/**/__tests__/` produced this god-node list:
```
1. `SiegeMember` - 55 edges
2. `BoardPage()` - 53 edges
3. `Post Suggestions Modal Handoff` - 40 edges
4. `postsTab` - 29 edges
5. `cn()` - 29 edges
6. `PostsPage()` - 28 edges
7. `BuildingType` - 27 edges
8. `MembersPage()` - 27 edges
9. `MemberRole` - 25 edges
10. `Self-Host on Azure Wiki Page` - 23 edges
```
(That run's artifacts are not committed here — only the tests-included artifacts are kept — but the list is reproducible by re-running with the same `.graphifyignore`.)
Three of ten — `SiegeMember`, `BuildingType`, `MemberRole` (positions 1, 7, 9) — are legitimate domain models a developer would identify.
The other seven illustrate a second pattern worth knowing about:
- **React top-level page components** (`BoardPage`, `PostsPage`, `MembersPage` at 2, 6, 8) — these import many things because they are entry points, not because they encode domain logic.
- **Class-merge utilities** — `cn()` (position 5) is a one-line Tailwind class-merging utility (`src/lib/utils.ts`). It scores 29 edges because every component that conditionally combines classes imports it. The connection count reflects a structural pattern (the React+Tailwind idiom), not semantic importance.
- **Document/wiki entities** — `Post Suggestions Modal Handoff` (position 3) is a planning document under `docs/design-refs/`; `Self-Host on Azure Wiki Page` (position 10) is a wiki article. Both are extracted as nodes alongside code entities and sort by edge count the same way.
This is informative for users tuning expectations: degree centrality on a React frontend with a shared `cn()` utility will surface that utility regardless of how aggressive the ignore filter is, because the connections are real even though the semantic importance is low.
## Finding 3 — Surprising connections cross language boundaries
Both runs surface INFERRED edges between Python backend types and TypeScript frontend types under "Surprising Connections (you probably didn't know these)." Examples:
```
- `AuthError` --uses--> `Member` [INFERRED]
backend/app/api/auth.py → frontend/src/api/types.ts
```
```
- `TestStartupValidation` --uses--> `MemberRole` [INFERRED]
backend/tests/test_auth.py → frontend/src/api/types.ts
```
A Python class does not "use" a TypeScript type at runtime. These are name-based similarity matches between identically-named constructs in two languages, surfaced as semantic relationships. The confidence values are flagged as INFERRED (avg 0.62 on this run), but the section header presents them as insights worth investigating.
The one cross-language INFERRED edge in this run that maps to a real design contract is:
```
- `PostPriorityResponse` --uses--> `PostPriorityConfig` [INFERRED]
backend/app/api/post_priority_config.py → frontend/src/api/posts.ts
```
The backend Pydantic schema and the frontend TypeScript type do mirror each other intentionally — this is the API contract. That relationship is real, but a developer who wrote either side already knows about it; INFERRED detection here recovers a fact rather than discovering one.
For corpora that mix Python and TypeScript with overlapping type names (common in monorepos with shared domain vocabulary), users should expect a high false-positive rate in this section and read it with the INFERRED confidence in mind.
## Finding 4 — Community cohesion is uniformly low on this corpus
Most of rsl-siege-manager's 141 communities (tests-included run) score between 0.05 and 0.17 on cohesion. The report itself flags 0.05 as "weakly interconnected" in the Suggested Questions section:
> "Should `Community 0` be split into smaller, more focused modules? — Cohesion score 0.05 - nodes in this community are weakly interconnected."
Community 0 has 112 nodes on this corpus.
rsl-siege-manager has a clean three-service architecture (backend / frontend / bot). The community-detection pass does not recover that structure as three large cohesive communities; it produces many small communities with low internal cohesion. Possible interpretations: the underlying graph has many INFERRED cross-language edges diluting the cluster signal, the chosen algorithm parameters favor over-segmentation on graphs of this density, or this corpus genuinely lacks tight intra-cluster topology that community detection can exploit.
A neutral framing for users: community cohesion is informative on this corpus mainly as a signal that the graph topology does not match the obvious three-tier mental model — which itself may be useful (it surfaces that the cross-language edges are doing the work). The "split this community" prompts the report generates from low cohesion scores are less actionable as direct architectural advice on this corpus.
## Finding 5 — Alembic migration docstrings surface as isolated nodes
The tests-included run reports 752 isolated nodes; the without-tests run reports 259. The leading examples are identical in both:
```
`initial schema Revision ID: 0001 Revises: Create Date: 2026-03-16`,
`add autofill and attack day preview columns to siege Revision ID: 0002 Revises:`,
`make siege date nullable Revision ID: 0003 Revises: 0002 Create Date: 2026-03-1`,
`Add post_priority_config table`, ...
```
These are Alembic migration revision docstrings parsed as standalone graph nodes. There are 17 migration files in this corpus. The isolated-node count growing from 259 to 752 when tests are added is dominated by test docstrings parsed the same way.
The report labels these as "possible documentation gaps or missing edges." For users with corpora that contain Alembic migrations, pytest docstrings, or other docstring-heavy auto-generated files, this label can be misleading — these are change annotations or test descriptions, not architectural entities with missing connections.
A `.graphifyignore` rule for `**/alembic/versions/*.py` reduces the isolated-node count materially on this corpus; users with similar setups may want a default recipe.
## Finding 6 — Suggested questions skew toward graph-property prompts
The Suggested Questions section consists primarily of two kinds of questions:
1. **Betweenness centrality prompts:** "Why does `_make_siege()` connect Community 12 to Community 0, Community 1, Community 3...?" The answer on this corpus is direct: `_make_siege()` creates the primary domain object, every test that touches a siege uses it, and the test suite spans the codebase — so the fixture is a betweenness bridge by construction.
2. **Inferred-edge audits:** "Are the 17 inferred relationships involving `SiegeMember` (e.g. with `Base` and `TestSeedDemoMembers`) actually correct?" These ask the developer to validate the tool's own low-confidence connections.
A genuinely concrete question in this section — "What is the exact relationship between `bootstrap-images.ps1` and `scripts/bootstrap-images.ps1`?" — is tagged AMBIGUOUS by the report. The answer is concrete (they are the same script referenced by two slightly different paths), but it is a file-naming observation, not an architectural insight.
For users hoping the Suggested Questions section will surface domain-level prompts ("how does authentication flow?", "what enforces the siege-day invariant?"), this corpus's section is dominated by graph-property meta-questions.
---
## What worked well on this corpus
- **Throughput:** 1886 nodes extracted in a few minutes at $0 cost. tree-sitter handles all 29 supported languages locally; LLM calls fire only for non-code files.
- **Genuine domain extractions are present:** `SiegeMember`, `BuildingType`, and `MemberRole` in the god-node list are correct. `PostPriorityResponse --uses--> PostPriorityConfig` is a real API contract that INFERRED detection picked up across the Python/TypeScript boundary.
- **`graph.html` visualization:** clear, navigable, easy to filter and search. Useful for browsing communities even when the labelled cohesion scores are low.
The underlying graph build is solid. The findings above are about how the report layer summarizes that graph into headline metrics — specifically, what those metrics surface on a well-tested cross-language full-stack web app.
---
## Suggested follow-ups
Patterns from this review that may be worth tracking upstream:
1. **Test-fixture suppression** — degree centrality on covered codebases consistently surfaces test factories; documenting the ignore-pattern recipe in a "first run on a codebase with tests" section would shorten the iteration loop for users.
2. **Cross-language INFERRED edges in monorepos** — name-based matches between Python and TypeScript types in mixed-language repos may warrant a higher confidence threshold or a "potential contract" label rather than the current "surprising connection" framing.
3. **Docstring-heavy files (Alembic, pytest)** — defaulting to skip migration `versions/` directories, or detecting and grouping docstring nodes that share a structural pattern, would reduce the isolated-node noise materially.
These are observations, not change requests — users running graphify on similar corpora may find the same patterns useful to know about.