immich server/: ac run immich-ladder

immich server/ @ 02063972e8 → c4be040b57 on ac/s6-ladder: run status completed.

Whole PR: PASS (static checks and oracles)

Certified commits
63
R1 38 · R2 21 · R3 3 · R4 1
Files moved
367
5 of them moved again by R3 renames; 0 files pinned
Specifier edits
2,474
in 515 files (whole-PR K2)
Rolled-back attempts
0
no commit failed its certificate
Wall time
1 h 55 m
one invocation
Plan cost when recorded
$0.1998
planner spend in this run $0.0000
FieldValue
Targetimmich (profile), package root server/, github.com/immich-app/immich
Commitsbase 02063972e8 → head c4be040b5739351507750669c3a179dd752f4a72; branch ac/s6-ladder (a local branch; the certificates name its trees)
Treesbase 424df72c3407dd1e7df5ee4e81a1d5fcd85cc01c → head 4e457bb4e806f1bc0a63b83141345e20edab0f57
Planplanned in this run: 59 steps, 367 moves, sha256 b4c7c548883c0635951f893c7717727f3d086a0c4e23b2db442e796dd416cc7f
Rungs requestedR0, R1, R2, R3, R4
Whole-PR digestsha256:9a5b2404631c2ac668462ad93fcbcd116637244e2b4f76e987bcc4e23e8be2b5
Costplanner spend in this run $0.0000 (budget run s6, mode auto); the plan cost $0.1998 when it was recorded; findings narration $0.0010 in 2 calls (Nemotron 3.5 Lightning (thinking off)), replayed
Injected faultnone

The plan: Nemotron draws the map

Deterministic seeds decided where files go; NVIDIA Nemotron 3 Ultra (on Nebius Token Factory) edited the draft in 3 candidates, and a critic call reviewed the chosen one; the validator gates both. The plan has 38 modules, 20 platform folders and 1 shared folder over 269 planned files: 259 from the deterministic seeds draft, 8 by the planner, 2 by the critic. 30 placements are marked contested. The chosen candidate is ultra#3.

The critic's review (plan.json, the model's own words): The plan correctly slices most business features into modules and keeps pure utilities in shared/. However, several validator warnings reveal misplaced plumbing and impure shared code: two repositories and a service live in shared/, five one‑file platform groups exist, three platform groups (ocr, version, app.controller) actually own tables or routes and belong in feature modules, and utils/editor.ts is only used by platform/media. Moving the offending files to their true owners and re‑classifying the three platform groups as modules removes all warnings without breaking cohesion. No unrelated merges are required.

The gate accepted 6 of the critic's 12 suggestions; 10 validator warnings remain on the plan (findings: plan-warning).

Placements the planner and the critic decided (10)
FileGroupDecided byRationale
src/app.common.tsplatform/bootstrapplannerBootstrap wiring for Express and telemetry; belongs to platform plumbing.
src/controllers/app.controller.tsplatform/bootstrapplannerRoot app controller only serves health/info endpoints; platform plumbing.
src/dtos/editing.dto.tsmodule/assetplannerEditing DTOs are used by asset edit flows.
src/dtos/env.dto.tsshared/sharedplannerEnvironment schema DTO is a pure type shared across config.
src/dtos/onboarding.dto.tsmodule/system-metadataplannerOnboarding DTOs used by system‑metadata controller.
src/repositories/app.repository.tsmodule/maintenancecriticOnly the maintenance module consumes this repository; fixes the impure‑shared warning.
src/utils/editor.tsplatform/mediacriticUtility is only imported by platform/media; moving it out of shared resolves the single‑consumer warning.
src/utils/object.tsshared/sharedplannerPlain object utilities.
src/utils/pagination.tsshared/sharedplannerPagination helpers used everywhere.
src/utils/profile-image.tsmodule/userplannerProfile image generation used by user feature.

plan.yaml · plan.md · the plan cost $0.1998 when it was recorded; a replay from the cassette costs $0

Before and after: the module graph

Folders
14 → 70
head: 38 modules, 20 platform, shared, 11 other folders
Files that changed folder
367 of 563
source files under the module root, tests included
Import pairs inside one folder
23.4% → 20.5%
479 → 421 file pairs
Largest import cycle
12 of 14 → 41 of 70
strongly connected folders, the composition root left out

At the base commit the 563 source files under src/ sit in 14 folders outside the layout; at the head commit 367 sit in the layout (286 in 38 feature modules, 61 in 20 platform folders and 20 in shared/) and 196 are still in 11 folders outside the layout. The file-level import pairs are the same 2,051 on both sides (a certified move keeps every import resolving to the same file); only their grouping changes. The share of pairs inside one folder falls: 479 of 2,051 (23.4%) at base, 421 of 2,051 (20.5%) at head. The largest blocks of internal pairs are src/schema/ 152, src/services/ 111, src/repositories/ 89 at base and src/schema/ 152, module/asset 32, module/user 26 at head. Grouping by feature doesn't remove the imports between features; it makes them visible. The findings below name what ties the modules together (1 god-injection base class and 2 module cycles). R4's rules freeze today's violations so they can't grow.

Import cycles at base: 12 folders

src/ src/commands/ src/controllers/ src/cores/ src/dtos/ src/emails/ src/maintenance/ src/middleware/ src/repositories/ src/schema/ src/services/ src/utils/

Import cycles at head: 41 folders, 2 folders

module/album module/asset module/auth module/config module/database-backup module/job module/library module/machine-learning module/maintenance module/map module/ocr module/partner module/person module/plugin module/queue module/search module/server module/session module/shared-link module/system-metadata module/tag module/user module/version module/workflow platform/access platform/cron platform/database platform/event platform/file platform/http-response platform/logging platform/media platform/move platform/storage shared src/ src/maintenance/ src/repositories/ src/schema/ src/services/ src/utils/

module/notification src/emails/

Files flow: where the 563 source files under src/ went
module/platform/shared/left where it was (not in the layout)
src/schema/ 168src/services/ 102src/controllers/ 82src/repositories/ 63src/dtos/ 55src/utils/ 43src/ 10src/commands/ 10src/emails/ 9src/middleware/ 8src/maintenance/ 6src/workers/ 3src/bin/ 2src/cores/ 2module/view 4module/notification 12module/activity 6module/api-key 6module/download 6module/job 6module/map 6module/memory 6module/partner 6module/stack 6module/trash 6module/integrity 5module/server 5module/session 5module/video-stream 5module/ocr 4module/person 8module/album 7module/shared-link 7module/timeline 6module/library 5module/queue 5module/system-metadata 7module/cluster-group 4module/config 10module/database-backup 6module/sync 8module/plugin 7module/duplicate 8module/tag 8module/workflow 8module/search 12module/machine-learning 1module/version 4module/asset 24module/user 19module/auth 15module/maintenance 13platform/transcoding 2platform/telemetry 2platform/metadata 4platform/cron 1platform/crypto 1platform/move 1platform/process 2platform/registry 7platform/database 4platform/bootstrap 3platform/media 8platform/event 2platform/access 3platform/storage 7platform/http-client 2platform/http-response 1platform/websocket 2platform/logging 6platform/check 1platform/file 2shared 20src/schema/ 168src/services/ 3src/controllers/ 1src/repositories/ 4src/dtos/ 1src/utils/ 2src/emails/ 9src/maintenance/ 1src/workers/ 3src/bin/ 2src/ 2

Left: the folders at the base commit, by size. Right: where their files are at the head commit, grouped by layout kind. A band is a number of files; every node is at least one label tall, so small groups are drawn larger than their share.

Table view
Base folderHead folderFiles
src/platform/bootstrap1
src/platform/database1
src/platform/registry1
src/shared5
src/src/2
src/bin/src/bin/2
src/commands/module/auth3
src/commands/module/maintenance1
src/commands/module/user2
src/commands/module/version1
src/commands/platform/check1
src/commands/platform/media1
src/commands/platform/registry1
src/controllers/module/activity2
src/controllers/module/album2
src/controllers/module/api-key2
src/controllers/module/asset5
src/controllers/module/auth5
src/controllers/module/cluster-group1
src/controllers/module/config5
src/controllers/module/database-backup2
src/controllers/module/download2
src/controllers/module/duplicate2
src/controllers/module/integrity1
src/controllers/module/job2
src/controllers/module/library2
src/controllers/module/maintenance2
src/controllers/module/map2
src/controllers/module/memory2
src/controllers/module/notification4
src/controllers/module/partner2
src/controllers/module/person3
src/controllers/module/plugin2
src/controllers/module/queue1
src/controllers/module/search2
src/controllers/module/server1
src/controllers/module/session1
src/controllers/module/shared-link2
src/controllers/module/stack2
src/controllers/module/sync2
src/controllers/module/system-metadata2
src/controllers/module/tag2
src/controllers/module/timeline2
src/controllers/module/trash2
src/controllers/module/user4
src/controllers/module/video-stream1
src/controllers/module/view1
src/controllers/module/workflow2
src/controllers/platform/bootstrap2
src/controllers/platform/registry2
src/controllers/src/controllers/1
src/cores/platform/storage2
src/dtos/module/activity1
src/dtos/module/album1
src/dtos/module/api-key1
src/dtos/module/asset8
src/dtos/module/auth1
src/dtos/module/cluster-group1
src/dtos/module/config2
src/dtos/module/database-backup1
src/dtos/module/download1
src/dtos/module/duplicate1
src/dtos/module/integrity1
src/dtos/module/job1
src/dtos/module/library1
src/dtos/module/maintenance1
src/dtos/module/map1
src/dtos/module/memory1
src/dtos/module/notification1
src/dtos/module/ocr1
src/dtos/module/partner1
src/dtos/module/person1
src/dtos/module/plugin3
src/dtos/module/queue2
src/dtos/module/search1
src/dtos/module/server1
src/dtos/module/session1
src/dtos/module/shared-link1
src/dtos/module/stack1
src/dtos/module/sync1
src/dtos/module/system-metadata2
src/dtos/module/tag1
src/dtos/module/timeline2
src/dtos/module/trash1
src/dtos/module/user6
src/dtos/module/video-stream1
src/dtos/module/workflow1
src/dtos/shared1
src/dtos/src/dtos/1
src/emails/src/emails/9
src/maintenance/module/maintenance5
src/maintenance/src/maintenance/1
src/middleware/module/asset1
src/middleware/module/auth2
src/middleware/platform/file1
src/middleware/platform/logging3
src/middleware/platform/websocket1
src/repositories/module/activity1
src/repositories/module/album2
src/repositories/module/api-key1
src/repositories/module/asset4
src/repositories/module/auth1
src/repositories/module/cluster-group1
src/repositories/module/download1
src/repositories/module/duplicate1
src/repositories/module/integrity1
src/repositories/module/job1
src/repositories/module/library1
src/repositories/module/machine-learning1
src/repositories/module/maintenance1
src/repositories/module/map1
src/repositories/module/memory1
src/repositories/module/notification3
src/repositories/module/ocr1
src/repositories/module/partner1
src/repositories/module/person2
src/repositories/module/plugin1
src/repositories/module/search1
src/repositories/module/server1
src/repositories/module/session1
src/repositories/module/shared-link2
src/repositories/module/stack1
src/repositories/module/sync2
src/repositories/module/system-metadata1
src/repositories/module/tag1
src/repositories/module/trash1
src/repositories/module/user1
src/repositories/module/version1
src/repositories/module/video-stream1
src/repositories/module/view1
src/repositories/module/workflow1
src/repositories/platform/access1
src/repositories/platform/cron1
src/repositories/platform/crypto1
src/repositories/platform/event1
src/repositories/platform/logging2
src/repositories/platform/media2
src/repositories/platform/metadata1
src/repositories/platform/move1
src/repositories/platform/process2
src/repositories/platform/registry1
src/repositories/platform/storage1
src/repositories/platform/telemetry1
src/repositories/platform/websocket1
src/repositories/src/repositories/4
src/schema/src/schema/168
src/services/module/activity2
src/services/module/album2
src/services/module/api-key2
src/services/module/asset5
src/services/module/auth3
src/services/module/cluster-group1
src/services/module/config2
src/services/module/database-backup2
src/services/module/download2
src/services/module/duplicate2
src/services/module/integrity2
src/services/module/job2
src/services/module/library1
src/services/module/maintenance2
src/services/module/map2
src/services/module/memory2
src/services/module/notification4
src/services/module/ocr2
src/services/module/partner2
src/services/module/person2
src/services/module/plugin1
src/services/module/queue2
src/services/module/search4
src/services/module/server2
src/services/module/session2
src/services/module/shared-link2
src/services/module/stack2
src/services/module/sync2
src/services/module/system-metadata2
src/services/module/tag2
src/services/module/timeline2
src/services/module/trash2
src/services/module/user5
src/services/module/version2
src/services/module/video-stream2
src/services/module/view2
src/services/module/workflow2
src/services/platform/database2
src/services/platform/media2
src/services/platform/metadata2
src/services/platform/registry2
src/services/platform/storage4
src/services/platform/telemetry1
src/services/platform/transcoding2
src/services/shared2
src/services/src/services/3
src/utils/module/asset1
src/utils/module/config1
src/utils/module/database-backup1
src/utils/module/duplicate2
src/utils/module/maintenance1
src/utils/module/search4
src/utils/module/sync1
src/utils/module/tag2
src/utils/module/user1
src/utils/module/workflow2
src/utils/platform/access2
src/utils/platform/database1
src/utils/platform/event1
src/utils/platform/file1
src/utils/platform/http-client2
src/utils/platform/http-response1
src/utils/platform/logging1
src/utils/platform/media3
src/utils/platform/metadata1
src/utils/shared12
src/utils/src/utils/2
src/workers/src/workers/3
Before: 14 folders at 02063972e8
imports along the orderimports against the order (they close cycles)imports inside one folder (diagonal)
src/bin/src/workers/src/services/src/controllers/src/repositories/src/emails/src/schema/src/dtos/src/utils/src/maintenance/src/cores/src/src/middleware/src/commands/src/bin/src/workers/src/services/src/controllers/src/repositories/src/emails/src/schema/src/dtos/src/utils/src/maintenance/src/cores/src/src/middleware/src/commands/

1,572 file pairs cross folders in 73 folder edges. Rows import columns. Folders are ordered importers first (strongly connected sets, then a greedy order inside each), so a cell below the diagonal is an import against the order. Darker means more file pairs (1, 2–3, 4–9, 10–29, 30+).

Table view
Importer folderImported folderFile pairsType-only
src/src/commands/10
src/src/controllers/10
src/src/dtos/70
src/src/maintenance/60
src/src/middleware/60
src/src/repositories/180
src/src/schema/61
src/src/services/60
src/src/utils/50
src/bin/src/20
src/bin/src/repositories/60
src/bin/src/services/10
src/bin/src/utils/20
src/commands/src/10
src/commands/src/dtos/10
src/commands/src/services/90
src/controllers/src/1171
src/controllers/src/dtos/11234
src/controllers/src/middleware/500
src/controllers/src/repositories/90
src/controllers/src/services/543
src/controllers/src/utils/130
src/cores/src/31
src/cores/src/repositories/80
src/cores/src/utils/20
src/dtos/src/909
src/dtos/src/repositories/10
src/dtos/src/schema/30
src/dtos/src/utils/110
src/emails/src/repositories/40
src/emails/src/utils/30
src/maintenance/src/71
src/maintenance/src/controllers/22
src/maintenance/src/cores/10
src/maintenance/src/dtos/70
src/maintenance/src/middleware/10
src/maintenance/src/repositories/121
src/maintenance/src/services/75
src/maintenance/src/utils/50
src/middleware/src/51
src/middleware/src/dtos/30
src/middleware/src/repositories/70
src/middleware/src/services/30
src/middleware/src/utils/60
src/repositories/src/11110
src/repositories/src/dtos/281
src/repositories/src/emails/40
src/repositories/src/schema/850
src/repositories/src/utils/300
src/schema/src/724
src/schema/src/dtos/50
src/schema/src/repositories/30
src/schema/src/utils/30
src/services/src/12925
src/services/src/cores/140
src/services/src/dtos/1241
src/services/src/maintenance/10
src/services/src/middleware/10
src/services/src/repositories/10918
src/services/src/schema/110
src/services/src/utils/1190
src/utils/src/348
src/utils/src/cores/30
src/utils/src/dtos/210
src/utils/src/middleware/10
src/utils/src/repositories/201
src/utils/src/schema/20
src/workers/src/60
src/workers/src/maintenance/10
src/workers/src/middleware/10
src/workers/src/repositories/60
src/workers/src/services/10
src/workers/src/utils/30
After: 70 folders at c4be040b57
imports along the orderimports against the order (they close cycles)imports inside one folder (diagonal)
src/bin/src/controllers/src/dtos/src/workers/platform/registrymodule/api-keymodule/cluster-groupmodule/activitymodule/downloadmodule/duplicatemodule/integritymodule/memorymodule/stackmodule/timelinemodule/trashmodule/video-streammodule/viewplatform/bootstrapplatform/checkplatform/http-clientplatform/metadataplatform/telemetryplatform/transcodingplatform/websocketmodule/syncmodule/assetmodule/partnermodule/usermodule/sessionplatform/mediamodule/maintenancemodule/database-backupmodule/jobmodule/queueplatform/cronsrc/maintenance/module/personmodule/notificationsrc/emails/src/schema/module/searchmodule/workflowmodule/pluginmodule/tagmodule/albummodule/mapmodule/shared-linkmodule/configmodule/authplatform/http-responsesrc/services/module/servermodule/versionplatform/storagemodule/libraryplatform/movesrc/repositories/module/ocrmodule/machine-learningplatform/databaseplatform/filemodule/system-metadataplatform/eventplatform/accessplatform/loggingsrc/utils/src/sharedplatform/cryptoplatform/processsrc/bin/src/controllers/src/dtos/src/workers/platform/registrymodule/api-keymodule/cluster-groupmodule/activitymodule/downloadmodule/duplicatemodule/integritymodule/memorymodule/stackmodule/timelinemodule/trashmodule/video-streammodule/viewplatform/bootstrapplatform/checkplatform/http-clientplatform/metadataplatform/telemetryplatform/transcodingplatform/websocketmodule/syncmodule/assetmodule/partnermodule/usermodule/sessionplatform/mediamodule/maintenancemodule/database-backupmodule/jobmodule/queueplatform/cronsrc/maintenance/module/personmodule/notificationsrc/emails/src/schema/module/searchmodule/workflowmodule/pluginmodule/tagmodule/albummodule/mapmodule/shared-linkmodule/configmodule/authplatform/http-responsesrc/services/module/servermodule/versionplatform/storagemodule/libraryplatform/movesrc/repositories/module/ocrmodule/machine-learningplatform/databaseplatform/filemodule/system-metadataplatform/eventplatform/accessplatform/loggingsrc/utils/src/sharedplatform/cryptoplatform/process

1,630 file pairs cross folders in 581 folder edges. Rows import columns. Folders are ordered importers first (strongly connected sets, then a greedy order inside each), so a cell below the diagonal is an import against the order. Darker means more file pairs (1, 2–3, 4–9, 10–29, 30+).

Table view
Importer folderImported folderFile pairsType-only
module/activitymodule/auth31
module/activitymodule/user10
module/activityplatform/database40
module/activityplatform/registry10
module/activityshared70
module/activitysrc/schema/20
module/albummodule/asset50
module/albummodule/auth31
module/albummodule/map20
module/albummodule/user10
module/albumplatform/database30
module/albumplatform/registry10
module/albumshared151
module/albumsrc/schema/50
module/albumsrc/utils/10
module/api-keymodule/auth31
module/api-keyplatform/access10
module/api-keyplatform/database30
module/api-keyplatform/registry10
module/api-keyshared80
module/api-keysrc/schema/20
module/api-keysrc/utils/10
module/assetmodule/auth155
module/assetmodule/ocr20
module/assetmodule/partner10
module/assetmodule/person10
module/assetmodule/tag10
module/assetmodule/user10
module/assetplatform/access40
module/assetplatform/database121
module/assetplatform/event10
module/assetplatform/file50
module/assetplatform/logging20
module/assetplatform/registry30
module/assetplatform/storage20
module/assetshared476
module/assetsrc/schema/110
module/assetsrc/utils/30
module/authmodule/config10
module/authmodule/user40
module/authplatform/access10
module/authplatform/database20
module/authplatform/http-response20
module/authplatform/logging20
module/authplatform/registry20
module/authshared151
module/authsrc/10
module/authsrc/services/30
module/cluster-groupmodule/activity10
module/cluster-groupmodule/auth31
module/cluster-groupmodule/user20
module/cluster-groupplatform/database10
module/cluster-groupplatform/registry10
module/cluster-groupshared60
module/cluster-groupsrc/schema/30
module/cluster-groupsrc/utils/10
module/configmodule/auth40
module/configmodule/system-metadata10
module/configplatform/event11
module/configplatform/logging10
module/configplatform/registry10
module/configplatform/storage10
module/configshared152
module/configsrc/repositories/10
module/configsrc/utils/10
module/database-backupmodule/auth21
module/database-backupmodule/config10
module/database-backupmodule/job10
module/database-backupmodule/maintenance10
module/database-backupmodule/system-metadata10
module/database-backupmodule/user10
module/database-backupplatform/cron10
module/database-backupplatform/event11
module/database-backupplatform/file20
module/database-backupplatform/http-response10
module/database-backupplatform/logging20
module/database-backupplatform/process10
module/database-backupplatform/storage20
module/database-backupshared50
module/database-backupsrc/10
module/database-backupsrc/maintenance/10
module/database-backupsrc/repositories/20
module/database-backupsrc/utils/10
module/downloadmodule/auth31
module/downloadplatform/database10
module/downloadplatform/file10
module/downloadplatform/registry10
module/downloadplatform/storage20
module/downloadshared60
module/downloadsrc/schema/10
module/duplicatemodule/asset60
module/duplicatemodule/auth31
module/duplicatemodule/search10
module/duplicateplatform/database20
module/duplicateplatform/registry10
module/duplicateshared81
module/duplicatesrc/repositories/10
module/duplicatesrc/schema/20
module/duplicatesrc/utils/10
module/integritymodule/auth21
module/integrityplatform/event11
module/integrityplatform/file20
module/integrityplatform/logging10
module/integrityplatform/registry10
module/integrityplatform/storage10
module/integrityshared91
module/integritysrc/10
module/integritysrc/schema/20
module/integritysrc/utils/10
module/jobmodule/asset10
module/jobmodule/auth21
module/jobmodule/queue40
module/jobplatform/event20
module/jobplatform/logging10
module/jobplatform/registry10
module/jobshared102
module/jobsrc/repositories/10
module/jobsrc/utils/10
module/librarymodule/auth10
module/libraryplatform/database10
module/libraryplatform/event11
module/libraryplatform/registry10
module/libraryplatform/storage10
module/libraryshared101
module/librarysrc/10
module/librarysrc/schema/30
module/librarysrc/utils/10
module/machine-learningmodule/config10
module/machine-learningplatform/logging10
module/maintenancemodule/auth53
module/maintenancemodule/config10
module/maintenancemodule/database-backup41
module/maintenancemodule/server42
module/maintenancemodule/system-metadata10
module/maintenancemodule/version11
module/maintenanceplatform/event32
module/maintenanceplatform/file10
module/maintenanceplatform/http-response20
module/maintenanceplatform/logging40
module/maintenanceplatform/process10
module/maintenanceplatform/registry21
module/maintenanceplatform/storage40
module/maintenanceshared143
module/maintenancesrc/10
module/maintenancesrc/maintenance/10
module/maintenancesrc/repositories/30
module/maintenancesrc/services/10
module/maintenancesrc/utils/20
module/mapmodule/asset10
module/mapmodule/auth31
module/mapmodule/system-metadata10
module/mapplatform/logging10
module/mapplatform/registry10
module/mapshared50
module/mapsrc/10
module/mapsrc/repositories/10
module/mapsrc/schema/30
module/memorymodule/asset62
module/memorymodule/auth41
module/memoryplatform/database20
module/memoryplatform/registry10
module/memoryshared111
module/memorysrc/schema/20
module/memorysrc/utils/10
module/notificationmodule/album10
module/notificationmodule/asset10
module/notificationmodule/auth62
module/notificationmodule/config30
module/notificationplatform/database10
module/notificationplatform/event11
module/notificationplatform/file10
module/notificationplatform/logging10
module/notificationplatform/registry20
module/notificationshared152
module/notificationsrc/emails/40
module/notificationsrc/schema/20
module/notificationsrc/utils/20
module/ocrmodule/machine-learning10
module/ocrplatform/database10
module/ocrplatform/registry10
module/ocrshared41
module/ocrsrc/schema/20
module/ocrsrc/utils/10
module/partnermodule/auth31
module/partnermodule/user20
module/partnerplatform/database20
module/partnerplatform/registry10
module/partnershared60
module/partnersrc/schema/20
module/personmodule/asset61
module/personmodule/auth52
module/personmodule/machine-learning10
module/personmodule/user10
module/personplatform/database40
module/personplatform/file20
module/personplatform/logging20
module/personplatform/registry10
module/personshared232
module/personsrc/schema/120
module/personsrc/utils/20
module/pluginmodule/auth10
module/pluginmodule/workflow20
module/pluginplatform/database10
module/pluginplatform/logging10
module/pluginplatform/registry10
module/pluginshared70
module/pluginsrc/schema/30
module/queuemodule/auth31
module/queuemodule/config10
module/queueplatform/event11
module/queueplatform/registry10
module/queueshared81
module/queuesrc/utils/10
module/searchmodule/album10
module/searchmodule/asset50
module/searchmodule/auth41
module/searchmodule/config20
module/searchmodule/person20
module/searchplatform/access20
module/searchplatform/database30
module/searchplatform/event11
module/searchplatform/registry20
module/searchshared131
module/searchsrc/repositories/10
module/searchsrc/schema/20
module/searchsrc/utils/20
module/servermodule/auth10
module/servermodule/system-metadata20
module/servermodule/user30
module/servermodule/version10
module/serverplatform/logging10
module/serverplatform/registry10
module/serverplatform/storage10
module/servershared90
module/serversrc/10
module/serversrc/repositories/10
module/serversrc/utils/10
module/sessionmodule/auth31
module/sessionplatform/database30
module/sessionplatform/event11
module/sessionplatform/registry10
module/sessionshared60
module/sessionsrc/schema/20
module/shared-linkmodule/album10
module/shared-linkmodule/asset50
module/shared-linkmodule/auth42
module/shared-linkplatform/database30
module/shared-linkplatform/http-response10
module/shared-linkplatform/logging10
module/shared-linkplatform/registry10
module/shared-linkshared100
module/shared-linksrc/schema/50
module/shared-linksrc/utils/10
module/stackmodule/asset30
module/stackmodule/auth41
module/stackplatform/database30
module/stackplatform/registry10
module/stackshared60
module/stacksrc/schema/20
module/stacksrc/utils/10
module/syncmodule/asset10
module/syncmodule/auth31
module/syncplatform/database10
module/syncplatform/http-response10
module/syncplatform/logging10
module/syncplatform/registry10
module/syncshared153
module/syncsrc/schema/40
module/system-metadatamodule/auth10
module/system-metadataplatform/registry10
module/system-metadatashared51
module/system-metadatasrc/schema/20
module/tagmodule/asset30
module/tagmodule/auth31
module/tagplatform/database40
module/tagplatform/logging10
module/tagplatform/registry10
module/tagshared91
module/tagsrc/schema/40
module/tagsrc/utils/10
module/timelinemodule/asset20
module/timelinemodule/auth31
module/timelineplatform/access10
module/timelineplatform/registry10
module/timelineshared60
module/trashmodule/asset20
module/trashmodule/auth31
module/trashplatform/registry10
module/trashshared60
module/trashsrc/schema/10
module/trashsrc/utils/10
module/usermodule/asset40
module/usermodule/auth72
module/usermodule/config10
module/usermodule/session20
module/usermodule/system-metadata20
module/userplatform/crypto10
module/userplatform/database30
module/userplatform/event11
module/userplatform/file30
module/userplatform/logging10
module/userplatform/media10
module/userplatform/registry20
module/userplatform/storage20
module/usershared294
module/usersrc/20
module/usersrc/schema/30
module/usersrc/services/20
module/usersrc/utils/20
module/versionmodule/server10
module/versionplatform/event11
module/versionplatform/registry10
module/versionshared41
module/versionsrc/10
module/versionsrc/schema/20
module/versionsrc/utils/10
module/video-streammodule/auth31
module/video-streammodule/config10
module/video-streamplatform/database10
module/video-streamplatform/event21
module/video-streamplatform/file20
module/video-streamplatform/logging10
module/video-streamplatform/media10
module/video-streamplatform/registry10
module/video-streamplatform/storage10
module/video-streamshared81
module/video-streamsrc/20
module/video-streamsrc/schema/20
module/viewmodule/asset20
module/viewmodule/auth31
module/viewplatform/database10
module/viewplatform/registry10
module/viewshared40
module/viewsrc/schema/10
module/workflowmodule/album20
module/workflowmodule/asset20
module/workflowmodule/auth41
module/workflowmodule/plugin30
module/workflowmodule/tag20
module/workflowplatform/database20
module/workflowplatform/event11
module/workflowplatform/registry20
module/workflowshared111
module/workflowsrc/schema/40
module/workflowsrc/utils/10
platform/accessmodule/auth10
platform/accessmodule/person40
platform/accessplatform/database20
platform/accessshared30
platform/accesssrc/schema/10
platform/bootstrapmodule/auth10
platform/bootstrapmodule/config10
platform/bootstrapmodule/maintenance10
platform/bootstrapplatform/logging10
platform/bootstrapplatform/telemetry10
platform/bootstrapplatform/websocket10
platform/bootstrapshared10
platform/bootstrapsrc/10
platform/bootstrapsrc/repositories/10
platform/bootstrapsrc/utils/10
platform/checksrc/10
platform/checksrc/services/10
platform/cronplatform/logging10
platform/databasemodule/asset20
platform/databasemodule/person10
platform/databasemodule/search20
platform/databaseplatform/registry10
platform/databaseshared93
platform/databasesrc/10
platform/databasesrc/schema/60
platform/eventmodule/auth10
platform/eventmodule/config10
platform/eventplatform/database10
platform/eventplatform/logging10
platform/eventshared31
platform/eventsrc/repositories/10
platform/filemodule/asset30
platform/filemodule/auth10
platform/fileplatform/logging30
platform/fileplatform/storage20
platform/fileshared31
platform/http-clientsrc/10
platform/http-responsemodule/auth10
platform/http-responseshared10
platform/loggingshared30
platform/loggingsrc/repositories/10
platform/loggingsrc/utils/10
platform/mediamodule/asset40
platform/mediamodule/config20
platform/mediamodule/machine-learning10
platform/mediamodule/ocr10
platform/mediaplatform/database30
platform/mediaplatform/logging10
platform/mediaplatform/registry10
platform/mediaplatform/storage10
platform/mediashared114
platform/mediasrc/30
platform/mediasrc/services/10
platform/mediasrc/utils/20
platform/metadatamodule/asset10
platform/metadatamodule/map10
platform/metadatamodule/tag10
platform/metadataplatform/database20
platform/metadataplatform/event11
platform/metadataplatform/logging10
platform/metadataplatform/registry10
platform/metadataplatform/storage10
platform/metadatashared61
platform/metadatasrc/schema/20
platform/metadatasrc/utils/10
platform/moveshared20
platform/movesrc/schema/20
platform/registrymodule/activity40
platform/registrymodule/album60
platform/registrymodule/api-key40
platform/registrymodule/asset140
platform/registrymodule/auth120
platform/registrymodule/cluster-group40
platform/registrymodule/config70
platform/registrymodule/database-backup30
platform/registrymodule/download40
platform/registrymodule/duplicate40
platform/registrymodule/integrity40
platform/registrymodule/job40
platform/registrymodule/library40
platform/registrymodule/machine-learning20
platform/registrymodule/maintenance100
platform/registrymodule/map40
platform/registrymodule/memory40
platform/registrymodule/notification80
platform/registrymodule/ocr30
platform/registrymodule/partner40
platform/registrymodule/person70
platform/registrymodule/plugin40
platform/registrymodule/queue30
platform/registrymodule/search50
platform/registrymodule/server40
platform/registrymodule/session40
platform/registrymodule/shared-link60
platform/registrymodule/stack40
platform/registrymodule/sync60
platform/registrymodule/system-metadata50
platform/registrymodule/tag40
platform/registrymodule/timeline20
platform/registrymodule/trash40
platform/registrymodule/user90
platform/registrymodule/version40
platform/registrymodule/video-stream40
platform/registrymodule/view40
platform/registrymodule/workflow50
platform/registryplatform/access30
platform/registryplatform/bootstrap10
platform/registryplatform/check10
platform/registryplatform/cron20
platform/registryplatform/crypto20
platform/registryplatform/database30
platform/registryplatform/event30
platform/registryplatform/file10
platform/registryplatform/http-client10
platform/registryplatform/logging60
platform/registryplatform/media40
platform/registryplatform/metadata30
platform/registryplatform/move20
platform/registryplatform/process30
platform/registryplatform/storage60
platform/registryplatform/telemetry40
platform/registryplatform/transcoding10
platform/registryplatform/websocket30
platform/registryshared31
platform/registrysrc/20
platform/registrysrc/maintenance/10
platform/registrysrc/repositories/60
platform/registrysrc/schema/10
platform/registrysrc/services/20
platform/storagemodule/asset30
platform/storagemodule/config20
platform/storagemodule/library10
platform/storagemodule/person10
platform/storagemodule/system-metadata10
platform/storageplatform/crypto10
platform/storageplatform/database10
platform/storageplatform/event11
platform/storageplatform/file10
platform/storageplatform/logging20
platform/storageplatform/move10
platform/storageplatform/registry20
platform/storageshared93
platform/storagesrc/10
platform/storagesrc/repositories/10
platform/storagesrc/utils/10
platform/telemetryplatform/event11
platform/telemetryplatform/logging10
platform/telemetryplatform/registry10
platform/telemetryshared30
platform/telemetrysrc/10
platform/telemetrysrc/repositories/10
platform/transcodingplatform/database10
platform/transcodingplatform/event11
platform/transcodingplatform/media10
platform/transcodingplatform/registry10
platform/transcodingplatform/storage10
platform/transcodingshared31
platform/transcodingsrc/10
platform/websocketmodule/asset10
platform/websocketmodule/auth10
platform/websocketmodule/notification10
platform/websocketmodule/server10
platform/websocketmodule/sync10
platform/websocketplatform/event10
platform/websocketplatform/logging10
platform/websocketsrc/repositories/10
platform/websocketsrc/utils/10
sharedmodule/asset30
sharedmodule/auth20
sharedmodule/config10
sharedmodule/maintenance10
sharedmodule/ocr10
sharedmodule/shared-link10
sharedmodule/user10
sharedplatform/access10
sharedplatform/database10
sharedplatform/event10
sharedplatform/file10
sharedplatform/logging10
sharedsrc/10
sharedsrc/repositories/10
sharedsrc/schema/10
sharedsrc/utils/20
src/module/system-metadata10
src/platform/database10
src/platform/registry10
src/shared20
src/src/repositories/10
src/src/schema/11
src/bin/module/auth10
src/bin/module/machine-learning10
src/bin/module/sync10
src/bin/platform/access10
src/bin/platform/database10
src/bin/platform/logging10
src/bin/platform/registry20
src/bin/shared10
src/bin/src/repositories/10
src/bin/src/utils/10
src/emails/module/notification40
src/emails/module/tag30
src/maintenance/src/10
src/repositories/platform/access10
src/repositories/platform/database10
src/repositories/platform/logging10
src/repositories/shared72
src/repositories/src/20
src/repositories/src/schema/20
src/schema/module/asset10
src/schema/module/person20
src/schema/module/plugin20
src/schema/platform/database40
src/schema/platform/logging20
src/schema/shared704
src/schema/src/10
src/schema/src/repositories/10
src/services/module/maintenance20
src/services/module/user10
src/services/platform/registry10
src/services/shared10
src/services/src/10
src/services/src/utils/10
src/utils/module/config10
src/utils/platform/logging10
src/utils/shared20
src/utils/src/10
src/workers/module/maintenance40
src/workers/platform/bootstrap20
src/workers/platform/logging10
src/workers/platform/registry30
src/workers/platform/telemetry10
src/workers/platform/websocket10
src/workers/shared10
src/workers/src/10
src/workers/src/repositories/10
src/workers/src/utils/30

Computed by architecture-cleaner analyzer (TypeScript module resolution), production importers under the module root with TypeScript 6.0.3, from git objects of both commits; stored in graph.json. Folders outside the layout are collapsed to their first directory under the module root, so this graph can count fewer folders than R4's report and the findings log.

The ladder

One transformation per commit: each of the 62 committed steps was certified against its parent before the next one started, with the static checks (K0, K1, K2, K3a, K3b, K3c, K4, K6, K7). Step 63 (R4) is certified with the oracles, by its rung certificate. The rung certificates of R1, R2, R3, R4 and the whole-PR certificate add the oracles (K8: tsc, unit, openapi). A FAIL rolls the commit back, and the step replans with the plan entries the failure names pinned in place.

RungStatusStepsRung certificateDuration
R0passed––3 m 56 s
R1certified38 certifiedPASS (static checks and oracles)1 h 00 m
R2certified21 certifiedPASS (static checks and oracles)35 m 37 s
R3certified3 certifiedPASS (static checks and oracles)7 m 49 s
R4certified1 certifiedPASS (static checks and oracles)4 m 40 s
Wall time: 1 h 55 m
preflightbaseline test runssteps (move, commit, certify)rung certificates with oracleswhole-PR certificate
1 h 34 m13 m 19 s
Table view
PhaseTime
preflight13.4 s
baseline test runs3 m 43 s
steps (move, commit, certify)1 h 34 m
rung certificates with oracles13 m 19 s
whole-PR certificate2 m 35 s
other (findings, report, bookkeeping)39.2 s
wall time1 h 55 m

No attempt failed: each of the 63 certified steps passed its certificate on its first attempt.

Every step

Open a step for its moves, its attempts and its certificate.

001 R1 module/activity certified 6 files moved, 17 specifier edits in 12 files, 2 m 21 s

Commit cf670ebc57ae1b6c7e64daf26194be6bfd086efb, tree e6c86400e6aba4584b58dce69f982ffda608e85f

6 paths moved
server/src/controllers/activity.controller.spec.ts
  → server/src/modules/activity/activity.controller.spec.ts
server/src/controllers/activity.controller.ts
  → server/src/modules/activity/activity.controller.ts
server/src/dtos/activity.dto.ts
  → server/src/modules/activity/activity.dto.ts
server/src/repositories/activity.repository.ts
  → server/src/modules/activity/activity.repository.ts
server/src/services/activity.service.spec.ts
  → server/src/modules/activity/activity.service.spec.ts
server/src/services/activity.service.ts
  → server/src/modules/activity/activity.service.ts

attempt 1: passed round 1, from 02063972e8, 6 moves, 2 m 21 s

Certificate: PASS (static checks) certificates/001-R1-module-activity.json

certificate JSON · digest sha256:909262855d4acc3f478bb34600f1209cda980a479c70a3cf7232da297ffac519

ac certify 02063972e8..11b856c607 (package root server/), profile immich
trees: 424df72c34..e6c86400e6
pathMap: 6 moves, 8 edited in place, 3450 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 6 moved files (9.6 s)
PASS  K1  Move-set integrity: 6 moves, 8 files edited in place, nothing added or deleted (1.4 s)
PASS  K2  Byte-span confinement: 17 specifier spans changed in 12 files; every other byte identical (0.8 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 17 rewritten specifiers keep their form (1.4 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.7 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.6 s)
PASS  K4  Location scan: 6 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.7 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/activity.service.spec.ts (moved to server/src/modules/activity/activity.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/activity.repository.ts (moved to server/src/modules/activity/activity.repository.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (97.4 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.7 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:909262855d4acc3f478bb34600f1209cda980a479c70a3cf7232da297ffac519
002 R1 module/album certified 7 files moved, 36 specifier edits in 25 files, 1 m 28 s

Commit e4df7c888915bbb55f64d559a23ee97ee0e476d5, tree 7a4771bd66ed18dad2052efd2bf68f1a51fbffa7

7 paths moved
server/src/controllers/album.controller.spec.ts
  → server/src/modules/album/album.controller.spec.ts
server/src/controllers/album.controller.ts
  → server/src/modules/album/album.controller.ts
server/src/dtos/album.dto.ts
  → server/src/modules/album/album.dto.ts
server/src/repositories/album-user.repository.ts
  → server/src/modules/album/album-user.repository.ts
server/src/repositories/album.repository.ts
  → server/src/modules/album/album.repository.ts
server/src/services/album.service.spec.ts
  → server/src/modules/album/album.service.spec.ts
server/src/services/album.service.ts
  → server/src/modules/album/album.service.ts

attempt 1: passed round 1, from cf670ebc57, 7 moves, 1 m 28 s

Certificate: PASS (static checks) certificates/002-R1-module-album.json

certificate JSON · digest sha256:1ebedaefc44a510108ffde5b4237a1b523f60cab352fdb8680e66b4ca19a2495

ac certify cf670ebc57..e95cca0892 (package root server/), profile immich
trees: e6c86400e6..7a4771bd66
pathMap: 7 moves, 20 edited in place, 3437 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 7 moved files (5.0 s)
PASS  K1  Move-set integrity: 7 moves, 20 files edited in place, nothing added or deleted (1.8 s)
PASS  K2  Byte-span confinement: 36 specifier spans changed in 25 files; every other byte identical (0.8 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 36 rewritten specifiers keep their form (1.5 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.0 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.6 s)
PASS  K4  Location scan: 7 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.4 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/album.service.spec.ts (moved to server/src/modules/album/album.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/album-user.repository.ts (moved to server/src/modules/album/album-user.repository.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.4 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:1ebedaefc44a510108ffde5b4237a1b523f60cab352fdb8680e66b4ca19a2495
003 R1 module/api-key certified 6 files moved, 14 specifier edits in 11 files, 1 m 28 s

Commit 36b507aec79264064153cd878600e7f1235381fe, tree 4bb492901defeb729b471f828d351dd938d6e019

6 paths moved
server/src/controllers/api-key.controller.spec.ts
  → server/src/modules/api-key/api-key.controller.spec.ts
server/src/controllers/api-key.controller.ts
  → server/src/modules/api-key/api-key.controller.ts
server/src/dtos/api-key.dto.ts
  → server/src/modules/api-key/api-key.dto.ts
server/src/repositories/api-key.repository.ts
  → server/src/modules/api-key/api-key.repository.ts
server/src/services/api-key.service.spec.ts
  → server/src/modules/api-key/api-key.service.spec.ts
server/src/services/api-key.service.ts
  → server/src/modules/api-key/api-key.service.ts

attempt 1: passed round 1, from e4df7c8889, 6 moves, 1 m 28 s

Certificate: PASS (static checks) certificates/003-R1-module-api-key.json

certificate JSON · digest sha256:fd9e7e9b81e47a6f8713483882095ec3abfbcfb6eb0e66d75ced27a3e5adb571

ac certify e4df7c8889..0e923b226a (package root server/), profile immich
trees: 7a4771bd66..4bb492901d
pathMap: 6 moves, 7 edited in place, 3451 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 6 moved files (5.0 s)
PASS  K1  Move-set integrity: 6 moves, 7 files edited in place, nothing added or deleted (1.8 s)
PASS  K2  Byte-span confinement: 14 specifier spans changed in 11 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 14 rewritten specifiers keep their form (1.5 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.9 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.7 s)
PASS  K4  Location scan: 6 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/api-key.service.spec.ts (moved to server/src/modules/api-key/api-key.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/api-key.repository.ts (moved to server/src/modules/api-key/api-key.repository.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.1 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.6 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:fd9e7e9b81e47a6f8713483882095ec3abfbcfb6eb0e66d75ced27a3e5adb571
004 R1 module/asset certified 24 files moved, 210 specifier edits in 120 files, 1 m 31 s

Commit bc9ffcea2cff24ff1d598a32d32e36aa703d43bd, tree 9c99e5147528c53367c0ef593cad3c44ea8bc65f

24 paths moved
server/src/controllers/asset-file.controller.ts
  → server/src/modules/asset/asset-file.controller.ts
server/src/controllers/asset-media.controller.spec.ts
  → server/src/modules/asset/asset-media.controller.spec.ts
server/src/controllers/asset-media.controller.ts
  → server/src/modules/asset/asset-media.controller.ts
server/src/controllers/asset.controller.spec.ts
  → server/src/modules/asset/asset.controller.spec.ts
server/src/controllers/asset.controller.ts
  → server/src/modules/asset/asset.controller.ts
server/src/dtos/asset-file.dto.ts
  → server/src/modules/asset/asset-file.dto.ts
server/src/dtos/asset-ids.response.dto.ts
  → server/src/modules/asset/asset-ids.response.dto.ts
server/src/dtos/asset-media-response.dto.ts
  → server/src/modules/asset/asset-media-response.dto.ts
server/src/dtos/asset-media.dto.ts
  → server/src/modules/asset/asset-media.dto.ts
server/src/dtos/asset-response.dto.ts
  → server/src/modules/asset/asset-response.dto.ts
server/src/dtos/asset.dto.ts
  → server/src/modules/asset/asset.dto.ts
server/src/dtos/editing.dto.ts
  → server/src/modules/asset/editing.dto.ts
server/src/dtos/exif.dto.ts
  → server/src/modules/asset/exif.dto.ts
server/src/middleware/asset-upload.interceptor.ts
  → server/src/modules/asset/asset-upload.interceptor.ts
server/src/repositories/asset-edit.repository.ts
  → server/src/modules/asset/asset-edit.repository.ts
server/src/repositories/asset-file.repository.ts
  → server/src/modules/asset/asset-file.repository.ts
server/src/repositories/asset-job.repository.ts
  → server/src/modules/asset/asset-job.repository.ts
server/src/repositories/asset.repository.ts
  → server/src/modules/asset/asset.repository.ts
server/src/services/asset-file.service.ts
  → server/src/modules/asset/asset-file.service.ts
server/src/services/asset-media.service.spec.ts
  → server/src/modules/asset/asset-media.service.spec.ts
server/src/services/asset-media.service.ts
  → server/src/modules/asset/asset-media.service.ts
server/src/services/asset.service.spec.ts
  → server/src/modules/asset/asset.service.spec.ts
server/src/services/asset.service.ts
  → server/src/modules/asset/asset.service.ts
server/src/utils/asset.util.ts
  → server/src/modules/asset/asset.util.ts

attempt 1: passed round 1, from 36b507aec7, 24 moves, 1 m 31 s

Certificate: PASS (static checks) certificates/004-R1-module-asset.json

certificate JSON · digest sha256:1b81fb81f24e437ed20222e0770206883820cabf3642374cb77ea823c98e62b9

ac certify 36b507aec7..4deb58fd2f (package root server/), profile immich
trees: 4bb492901d..9c99e51475
pathMap: 24 moves, 103 edited in place, 3337 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 24 moved files (5.0 s)
PASS  K1  Move-set integrity: 24 moves, 103 files edited in place, nothing added or deleted (1.8 s)
PASS  K2  Byte-span confinement: 210 specifier spans changed in 120 files; every other byte identical (0.9 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 210 rewritten specifiers keep their form (1.5 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.2 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.7 s)
PASS  K4  Location scan: 24 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (9 findings in docs, comments or ungated coverage settings) (5.8 s)
        finding (stack-text) server/src/services/asset-media.service.ts: moved to server/src/modules/asset/asset-media.service.ts; 1 stack-trace reads passed along as text (line 224); their frames now name the new path
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/asset-file.service.ts (moved to server/src/modules/asset/asset-file.service.ts)
        … 8 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.9 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:1b81fb81f24e437ed20222e0770206883820cabf3642374cb77ea823c98e62b9
005 R1 module/auth certified 15 files moved, 177 specifier edits in 117 files, 1 m 30 s

Commit a6bcc0fa8c5a8429257f703d2ab089bcc50f33b7, tree b84e0e20724a378407c0a19b80a4737205983444

15 paths moved
server/src/commands/grant-admin.ts
  → server/src/modules/auth/grant-admin.ts
server/src/commands/oauth-login.ts
  → server/src/modules/auth/oauth-login.ts
server/src/commands/password-login.ts
  → server/src/modules/auth/password-login.ts
server/src/controllers/auth-admin.controller.ts
  → server/src/modules/auth/auth-admin.controller.ts
server/src/controllers/auth.controller.spec.ts
  → server/src/modules/auth/auth.controller.spec.ts
server/src/controllers/auth.controller.ts
  → server/src/modules/auth/auth.controller.ts
server/src/controllers/oauth.controller.spec.ts
  → server/src/modules/auth/oauth.controller.spec.ts
server/src/controllers/oauth.controller.ts
  → server/src/modules/auth/oauth.controller.ts
server/src/dtos/auth.dto.ts
  → server/src/modules/auth/auth.dto.ts
server/src/middleware/auth.guard.spec.ts
  → server/src/modules/auth/auth.guard.spec.ts
server/src/middleware/auth.guard.ts
  → server/src/modules/auth/auth.guard.ts
server/src/repositories/oauth.repository.ts
  → server/src/modules/auth/oauth.repository.ts
server/src/services/auth-admin.service.ts
  → server/src/modules/auth/auth-admin.service.ts
server/src/services/auth.service.spec.ts
  → server/src/modules/auth/auth.service.spec.ts
server/src/services/auth.service.ts
  → server/src/modules/auth/auth.service.ts

attempt 1: passed round 1, from bc9ffcea2c, 15 moves, 1 m 30 s

Certificate: PASS (static checks) certificates/005-R1-module-auth.json

certificate JSON · digest sha256:e66b3538df82d31cd5ed77ee1f7aece3a725e31b867dfc54bfec8b2dd5d1c0bb

ac certify bc9ffcea2c..b8191fa418 (package root server/), profile immich
trees: 9c99e51475..b84e0e2072
pathMap: 15 moves, 107 edited in place, 3342 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 15 moved files (5.0 s)
PASS  K1  Move-set integrity: 15 moves, 107 files edited in place, nothing added or deleted (2.2 s)
PASS  K2  Byte-span confinement: 177 specifier spans changed in 117 files; every other byte identical (0.8 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 177 rewritten specifiers keep their form (1.5 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.6 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.8 s)
PASS  K4  Location scan: 15 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (stack-text) server/src/services/auth.service.ts: moved to server/src/modules/auth/auth.service.ts; 1 stack-trace reads passed along as text (line 403); their frames now name the new path
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/auth-admin.service.ts (moved to server/src/modules/auth/auth-admin.service.ts)
        … 7 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.4 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:e66b3538df82d31cd5ed77ee1f7aece3a725e31b867dfc54bfec8b2dd5d1c0bb
006 R1 module/cluster-group certified 4 files moved, 14 specifier edits in 12 files, 1 m 30 s

Commit 2402a3abeeb4041e4dd10843e084f705969e9bd2, tree 8a3fde209ddbc272fe9e70c8f133ddc3a2c3da31

4 paths moved
server/src/controllers/cluster-group.controller.ts
  → server/src/modules/cluster-group/cluster-group.controller.ts
server/src/dtos/cluster-group.dto.ts
  → server/src/modules/cluster-group/cluster-group.dto.ts
server/src/repositories/cluster-group.repository.ts
  → server/src/modules/cluster-group/cluster-group.repository.ts
server/src/services/cluster-group.service.ts
  → server/src/modules/cluster-group/cluster-group.service.ts

attempt 1: passed round 1, from a6bcc0fa8c, 4 moves, 1 m 30 s

Certificate: PASS (static checks) certificates/006-R1-module-cluster-group.json

certificate JSON · digest sha256:b0fd9e09196a87239dbae7de95ca005fd53104a8e62ad99b73cc9db8dc7d0800

ac certify a6bcc0fa8c..99ba1b5b78 (package root server/), profile immich
trees: b84e0e2072..8a3fde209d
pathMap: 4 moves, 10 edited in place, 3450 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 4 moved files (5.2 s)
PASS  K1  Move-set integrity: 4 moves, 10 files edited in place, nothing added or deleted (2.4 s)
PASS  K2  Byte-span confinement: 14 specifier spans changed in 12 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 14 rewritten specifiers keep their form (1.5 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.0 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.6 s)
PASS  K4  Location scan: 4 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (7 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/cluster-group.service.ts (moved to server/src/modules/cluster-group/cluster-group.service.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/cluster-group.repository.ts (moved to server/src/modules/cluster-group/cluster-group.repository.ts)
        … 5 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.3 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:b0fd9e09196a87239dbae7de95ca005fd53104a8e62ad99b73cc9db8dc7d0800
007 R1 module/config certified 10 files moved, 66 specifier edits in 49 files, 1 m 30 s

Commit 06316bd4bad503ee71d7e775f920c1c64068c81c, tree 6b5fcf2a98f518f4a31421f3090a494cd3fa5f2c

10 paths moved
server/src/controllers/config-admin.controller.ts
  → server/src/modules/config/config-admin.controller.ts
server/src/controllers/config-public.controller.ts
  → server/src/modules/config/config-public.controller.ts
server/src/controllers/config-user.controller.ts
  → server/src/modules/config/config-user.controller.ts
server/src/controllers/system-config.controller.spec.ts
  → server/src/modules/config/system-config.controller.spec.ts
server/src/controllers/system-config.controller.ts
  → server/src/modules/config/system-config.controller.ts
server/src/dtos/config.dto.spec.ts
  → server/src/modules/config/config.dto.spec.ts
server/src/dtos/config.dto.ts
  → server/src/modules/config/config.dto.ts
server/src/services/system-config.service.spec.ts
  → server/src/modules/config/system-config.service.spec.ts
server/src/services/system-config.service.ts
  → server/src/modules/config/system-config.service.ts
server/src/utils/config.ts
  → server/src/modules/config/config.ts

attempt 1: passed round 1, from 2402a3abee, 10 moves, 1 m 30 s

Certificate: PASS (static checks) certificates/007-R1-module-config.json

certificate JSON · digest sha256:a514c0d32d79c36971870eedb04ffc4b409e3065ea9423561e61534175fbfe6b

ac certify 2402a3abee..49c0dc4c4d (package root server/), profile immich
trees: 8a3fde209d..6b5fcf2a98
pathMap: 10 moves, 40 edited in place, 3414 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 10 moved files (5.1 s)
PASS  K1  Move-set integrity: 10 moves, 40 files edited in place, nothing added or deleted (2.4 s)
PASS  K2  Byte-span confinement: 66 specifier spans changed in 49 files; every other byte identical (0.8 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 66 rewritten specifiers keep their form (1.5 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.1 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.7 s)
PASS  K4  Location scan: 10 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (7 findings in docs, comments or ungated coverage settings) (5.4 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/system-config.service.spec.ts (moved to server/src/modules/config/system-config.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/system-config.service.spec.ts (moved to server/src/modules/config/system-config.service.spec.ts)
        … 5 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.1 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:a514c0d32d79c36971870eedb04ffc4b409e3065ea9423561e61534175fbfe6b
008 R1 module/database-backup certified 6 files moved, 15 specifier edits in 10 files, 1 m 29 s

Commit d74f93bf1f35a8774b4511c45eb98ae334089728, tree d993961cea2ad74aede89d35917501e858790cd7

6 paths moved
server/src/controllers/database-backup.controller.spec.ts
  → server/src/modules/database-backup/database-backup.controller.spec.ts
server/src/controllers/database-backup.controller.ts
  → server/src/modules/database-backup/database-backup.controller.ts
server/src/dtos/database-backup.dto.ts
  → server/src/modules/database-backup/database-backup.dto.ts
server/src/services/database-backup.service.spec.ts
  → server/src/modules/database-backup/database-backup.service.spec.ts
server/src/services/database-backup.service.ts
  → server/src/modules/database-backup/database-backup.service.ts
server/src/utils/database-backups.ts
  → server/src/modules/database-backup/database-backups.ts

attempt 1: passed round 1, from 06316bd4ba, 6 moves, 1 m 29 s

Certificate: PASS (static checks) certificates/008-R1-module-database-backup.json

certificate JSON · digest sha256:9aaae7b61cdc60655a1e5f494e8a8529ad1d84bcdf5c1b80f6f72b2c6314b895

ac certify 06316bd4ba..3d9cecfcaf (package root server/), profile immich
trees: 6b5fcf2a98..d993961cea
pathMap: 6 moves, 6 edited in place, 3452 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 6 moved files (5.1 s)
PASS  K1  Move-set integrity: 6 moves, 6 files edited in place, nothing added or deleted (2.3 s)
PASS  K2  Byte-span confinement: 15 specifier spans changed in 10 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 15 rewritten specifiers keep their form (1.5 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.1 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.6 s)
PASS  K4  Location scan: 6 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (7 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/database-backup.service.spec.ts (moved to server/src/modules/database-backup/database-backup.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/database-backup.service.spec.ts (moved to server/src/modules/database-backup/database-backup.service.spec.ts)
        … 5 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.5 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:9aaae7b61cdc60655a1e5f494e8a8529ad1d84bcdf5c1b80f6f72b2c6314b895
009 R1 module/download certified 6 files moved, 12 specifier edits in 9 files, 1 m 28 s

Commit 380b8ab16c16033f093b1928eb3a0fc7eb64cace, tree cd94b4f6f8aa3039d4518418beebe9437fbc5c58

6 paths moved
server/src/controllers/download.controller.spec.ts
  → server/src/modules/download/download.controller.spec.ts
server/src/controllers/download.controller.ts
  → server/src/modules/download/download.controller.ts
server/src/dtos/download.dto.ts
  → server/src/modules/download/download.dto.ts
server/src/repositories/download.repository.ts
  → server/src/modules/download/download.repository.ts
server/src/services/download.service.spec.ts
  → server/src/modules/download/download.service.spec.ts
server/src/services/download.service.ts
  → server/src/modules/download/download.service.ts

attempt 1: passed round 1, from d74f93bf1f, 6 moves, 1 m 28 s

Certificate: PASS (static checks) certificates/009-R1-module-download.json

certificate JSON · digest sha256:d6229888093b5ca221c62cde71153b1824cc8e537f58336300727c76e79c670c

ac certify d74f93bf1f..ccef374134 (package root server/), profile immich
trees: d993961cea..cd94b4f6f8
pathMap: 6 moves, 5 edited in place, 3453 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 6 moved files (5.1 s)
PASS  K1  Move-set integrity: 6 moves, 5 files edited in place, nothing added or deleted (1.9 s)
PASS  K2  Byte-span confinement: 12 specifier spans changed in 9 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 12 rewritten specifiers keep their form (1.5 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.6 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.6 s)
PASS  K4  Location scan: 6 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/download.service.spec.ts (moved to server/src/modules/download/download.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/download.repository.ts (moved to server/src/modules/download/download.repository.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.7 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:d6229888093b5ca221c62cde71153b1824cc8e537f58336300727c76e79c670c
010 R1 module/duplicate certified 8 files moved, 16 specifier edits in 12 files, 1 m 29 s

Commit d49c79905bb39b3c3c41f1f8af697a4d90c3e5b1, tree 24cfcfceb2199535a71d25fab89763bfb02a28ea

8 paths moved
server/src/controllers/duplicate.controller.spec.ts
  → server/src/modules/duplicate/duplicate.controller.spec.ts
server/src/controllers/duplicate.controller.ts
  → server/src/modules/duplicate/duplicate.controller.ts
server/src/dtos/duplicate.dto.ts
  → server/src/modules/duplicate/duplicate.dto.ts
server/src/repositories/duplicate.repository.ts
  → server/src/modules/duplicate/duplicate.repository.ts
server/src/services/duplicate.service.spec.ts
  → server/src/modules/duplicate/duplicate.service.spec.ts
server/src/services/duplicate.service.ts
  → server/src/modules/duplicate/duplicate.service.ts
server/src/utils/duplicate.spec.ts
  → server/src/modules/duplicate/duplicate.spec.ts
server/src/utils/duplicate.ts
  → server/src/modules/duplicate/duplicate.ts

attempt 1: passed round 1, from 380b8ab16c, 8 moves, 1 m 29 s

Certificate: PASS (static checks) certificates/010-R1-module-duplicate.json

certificate JSON · digest sha256:9716936939bbc76b643d524a99c73dad830faa3fc6fb9df6f783f598e0bc0f67

ac certify 380b8ab16c..e92962149e (package root server/), profile immich
trees: cd94b4f6f8..24cfcfceb2
pathMap: 8 moves, 7 edited in place, 3449 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 8 moved files (5.2 s)
PASS  K1  Move-set integrity: 8 moves, 7 files edited in place, nothing added or deleted (1.9 s)
PASS  K2  Byte-span confinement: 16 specifier spans changed in 12 files; every other byte identical (0.8 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 16 rewritten specifiers keep their form (1.5 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.9 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.7 s)
PASS  K4  Location scan: 8 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (9 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (stack-text) server/src/services/duplicate.service.ts: moved to server/src/modules/duplicate/duplicate.service.ts; 1 stack-trace reads passed along as text (line 104); their frames now name the new path
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/duplicate.service.spec.ts (moved to server/src/modules/duplicate/duplicate.service.spec.ts)
        … 8 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.7 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:9716936939bbc76b643d524a99c73dad830faa3fc6fb9df6f783f598e0bc0f67
011 R1 module/integrity certified 5 files moved, 12 specifier edits in 10 files, 1 m 29 s

Commit 22f3b96735045bf904a588d7b4d25854906759be, tree be15f4a66ae811c0594cab9f5bdedda27b1a47e6

5 paths moved
server/src/controllers/integrity-admin.controller.ts
  → server/src/modules/integrity/integrity-admin.controller.ts
server/src/dtos/integrity.dto.ts
  → server/src/modules/integrity/integrity.dto.ts
server/src/repositories/integrity.repository.ts
  → server/src/modules/integrity/integrity.repository.ts
server/src/services/integrity.service.spec.ts
  → server/src/modules/integrity/integrity.service.spec.ts
server/src/services/integrity.service.ts
  → server/src/modules/integrity/integrity.service.ts

attempt 1: passed round 1, from d49c79905b, 5 moves, 1 m 29 s

Certificate: PASS (static checks) certificates/011-R1-module-integrity.json

certificate JSON · digest sha256:18639561a69abbe4dcbf806a0beb928aebde0867ab37d0c51de34b8e8d626503

ac certify d49c79905b..5036d72a59 (package root server/), profile immich
trees: 24cfcfceb2..be15f4a66a
pathMap: 5 moves, 7 edited in place, 3452 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 5 moved files (5.1 s)
PASS  K1  Move-set integrity: 5 moves, 7 files edited in place, nothing added or deleted (2.3 s)
PASS  K2  Byte-span confinement: 12 specifier spans changed in 10 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 12 rewritten specifiers keep their form (1.6 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.3 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.7 s)
PASS  K4  Location scan: 5 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.1 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/integrity.service.spec.ts (moved to server/src/modules/integrity/integrity.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/integrity.repository.ts (moved to server/src/modules/integrity/integrity.repository.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.2 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:18639561a69abbe4dcbf806a0beb928aebde0867ab37d0c51de34b8e8d626503
012 R1 module/job certified 6 files moved, 24 specifier edits in 22 files, 1 m 29 s

Commit 0c9d579e786ba887e45a23c7a81907c2a376d84b, tree 77c6fb5d99b4593c19bac1c3724c0c8481b8f0d8

6 paths moved
server/src/controllers/job.controller.spec.ts
  → server/src/modules/job/job.controller.spec.ts
server/src/controllers/job.controller.ts
  → server/src/modules/job/job.controller.ts
server/src/dtos/job.dto.ts
  → server/src/modules/job/job.dto.ts
server/src/repositories/job.repository.ts
  → server/src/modules/job/job.repository.ts
server/src/services/job.service.spec.ts
  → server/src/modules/job/job.service.spec.ts
server/src/services/job.service.ts
  → server/src/modules/job/job.service.ts

attempt 1: passed round 1, from 22f3b96735, 6 moves, 1 m 29 s

Certificate: PASS (static checks) certificates/012-R1-module-job.json

certificate JSON · digest sha256:7586bf31ee2d6700f5a08f9ddf663cbfc1396b5ab2bfba35e872f39d2f3eeb64

ac certify 22f3b96735..2254a40c73 (package root server/), profile immich
trees: be15f4a66a..77c6fb5d99
pathMap: 6 moves, 18 edited in place, 3440 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 6 moved files (5.1 s)
PASS  K1  Move-set integrity: 6 moves, 18 files edited in place, nothing added or deleted (2.0 s)
PASS  K2  Byte-span confinement: 24 specifier spans changed in 22 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 24 rewritten specifiers keep their form (1.6 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.6 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.6 s)
PASS  K4  Location scan: 6 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.2 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/job.service.spec.ts (moved to server/src/modules/job/job.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/job.repository.ts (moved to server/src/modules/job/job.repository.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.8 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:7586bf31ee2d6700f5a08f9ddf663cbfc1396b5ab2bfba35e872f39d2f3eeb64
013 R1 module/library certified 5 files moved, 19 specifier edits in 14 files, 1 m 29 s

Commit 23352efd59d54f0a6c4376770e21b0187a52d941, tree accbe06180f94d44f2d8f1ab313e0725bfac7230

5 paths moved
server/src/controllers/library.controller.spec.ts
  → server/src/modules/library/library.controller.spec.ts
server/src/controllers/library.controller.ts
  → server/src/modules/library/library.controller.ts
server/src/dtos/library.dto.ts
  → server/src/modules/library/library.dto.ts
server/src/repositories/library.repository.ts
  → server/src/modules/library/library.repository.ts
server/src/services/library.service.ts
  → server/src/modules/library/library.service.ts

attempt 1: passed round 1, from 0c9d579e78, 5 moves, 1 m 29 s

Certificate: PASS (static checks) certificates/013-R1-module-library.json

certificate JSON · digest sha256:5f4a8c285905f27f4117c867d4dc70ec29faa7eac350a62b1c9ab4b7621113cb

ac certify 0c9d579e78..96c5114ac5 (package root server/), profile immich
trees: 77c6fb5d99..accbe06180
pathMap: 5 moves, 10 edited in place, 3449 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 5 moved files (5.1 s)
PASS  K1  Move-set integrity: 5 moves, 10 files edited in place, nothing added or deleted (2.1 s)
PASS  K2  Byte-span confinement: 19 specifier spans changed in 14 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 19 rewritten specifiers keep their form (1.6 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.8 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.9 s)
PASS  K4  Location scan: 5 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (7 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/library.service.ts (moved to server/src/modules/library/library.service.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/library.repository.ts (moved to server/src/modules/library/library.repository.ts)
        … 5 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.4 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:5f4a8c285905f27f4117c867d4dc70ec29faa7eac350a62b1c9ab4b7621113cb
014 R1 module/machine-learning certified 1 file moved, 10 specifier edits in 10 files, 1 m 29 s

Commit 17296cd4274fce3ffcaa75bec96588f4be9d3b28, tree 7b7a66bed340b1762fc6ed1675903697e572e911

1 path moved
server/src/repositories/machine-learning.repository.ts
  → server/src/modules/machine-learning/machine-learning.repository.ts

attempt 1: passed round 1, from 23352efd59, 1 move, 1 m 29 s

Certificate: PASS (static checks) certificates/014-R1-module-machine-learning.json

certificate JSON · digest sha256:78e92bbee77101fb14c4d94d8fdedac11cb680a4b025844230132af1f8098b22

ac certify 23352efd59..2675047a3b (package root server/), profile immich
trees: accbe06180..7b7a66bed3
pathMap: 1 moves, 10 edited in place, 3453 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 1 moved files (5.2 s)
PASS  K1  Move-set integrity: 1 moves, 10 files edited in place, nothing added or deleted (2.2 s)
PASS  K2  Byte-span confinement: 10 specifier spans changed in 10 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 10 rewritten specifiers keep their form (1.6 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.5 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.7 s)
PASS  K4  Location scan: 1 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (2 findings in docs, comments or ungated coverage settings) (5.2 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/machine-learning.repository.ts (moved to server/src/modules/machine-learning/machine-learning.repository.ts)
        finding (old-path-in-docs) docs/docs/developer/architecture.mdx: line 60: 'src/repositories' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/machine-learning.repository.ts (moved to server/src/modules/machine-learning/machine-learning.repository.ts)
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.9 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:78e92bbee77101fb14c4d94d8fdedac11cb680a4b025844230132af1f8098b22
015 R1 module/maintenance certified 13 files moved, 42 specifier edits in 25 files, 1 m 29 s

Commit e896acc97857f42d0ef4a79fec48218014395189, tree c84fd64f006957fe709395b5da10492e88bb9c90

13 paths moved
server/src/commands/maintenance-mode.ts
  → server/src/modules/maintenance/maintenance-mode.ts
server/src/controllers/maintenance.controller.spec.ts
  → server/src/modules/maintenance/maintenance.controller.spec.ts
server/src/controllers/maintenance.controller.ts
  → server/src/modules/maintenance/maintenance.controller.ts
server/src/dtos/maintenance.dto.ts
  → server/src/modules/maintenance/maintenance.dto.ts
server/src/maintenance/maintenance-auth.guard.ts
  → server/src/modules/maintenance/maintenance-auth.guard.ts
server/src/maintenance/maintenance-websocket.repository.ts
  → server/src/modules/maintenance/maintenance-websocket.repository.ts
server/src/maintenance/maintenance-worker.controller.ts
  → server/src/modules/maintenance/maintenance-worker.controller.ts
server/src/maintenance/maintenance-worker.service.spec.ts
  → server/src/modules/maintenance/maintenance-worker.service.spec.ts
server/src/maintenance/maintenance-worker.service.ts
  → server/src/modules/maintenance/maintenance-worker.service.ts
server/src/repositories/app.repository.ts
  → server/src/modules/maintenance/app.repository.ts
server/src/services/maintenance.service.spec.ts
  → server/src/modules/maintenance/maintenance.service.spec.ts
server/src/services/maintenance.service.ts
  → server/src/modules/maintenance/maintenance.service.ts
server/src/utils/maintenance.ts
  → server/src/modules/maintenance/maintenance.ts

attempt 1: passed round 1, from 17296cd427, 13 moves, 1 m 29 s

Certificate: PASS (static checks) certificates/015-R1-module-maintenance.json

certificate JSON · digest sha256:19d4f2d25ed4cf1bccd3110486a7201ffd6d9bd9822bb93f073390d0a27d78d1

ac certify 17296cd427..0fd3eed055 (package root server/), profile immich
trees: 7b7a66bed3..c84fd64f00
pathMap: 13 moves, 15 edited in place, 3436 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 13 moved files (5.1 s)
PASS  K1  Move-set integrity: 13 moves, 15 files edited in place, nothing added or deleted (2.0 s)
PASS  K2  Byte-span confinement: 42 specifier spans changed in 25 files; every other byte identical (0.8 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 42 rewritten specifiers keep their form (1.6 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.7 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.6 s)
PASS  K4  Location scan: 13 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (9 findings in docs, comments or ungated coverage settings) (5.4 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/maintenance.service.spec.ts (moved to server/src/modules/maintenance/maintenance.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/app.repository.ts (moved to server/src/modules/maintenance/app.repository.ts)
        … 7 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.2 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:19d4f2d25ed4cf1bccd3110486a7201ffd6d9bd9822bb93f073390d0a27d78d1
016 R1 module/map certified 6 files moved, 15 specifier edits in 13 files, 1 m 28 s

Commit 07eedaa5ee692b1347215869e3b2a93caf8ff69c, tree fdcdfa4860055afde9e286504dc25f8be7eeef21

6 paths moved
server/src/controllers/map.controller.spec.ts
  → server/src/modules/map/map.controller.spec.ts
server/src/controllers/map.controller.ts
  → server/src/modules/map/map.controller.ts
server/src/dtos/map.dto.ts
  → server/src/modules/map/map.dto.ts
server/src/repositories/map.repository.ts
  → server/src/modules/map/map.repository.ts
server/src/services/map.service.spec.ts
  → server/src/modules/map/map.service.spec.ts
server/src/services/map.service.ts
  → server/src/modules/map/map.service.ts

attempt 1: passed round 1, from e896acc978, 6 moves, 1 m 28 s

Certificate: PASS (static checks) certificates/016-R1-module-map.json

certificate JSON · digest sha256:c7010d48a6087c57c6957d620d7fbcf20fe586bb1227e0574b71752ee67bc120

ac certify e896acc978..e7a134f18a (package root server/), profile immich
trees: c84fd64f00..fdcdfa4860
pathMap: 6 moves, 9 edited in place, 3449 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 6 moved files (5.1 s)
PASS  K1  Move-set integrity: 6 moves, 9 files edited in place, nothing added or deleted (2.0 s)
PASS  K2  Byte-span confinement: 15 specifier spans changed in 13 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 15 rewritten specifiers keep their form (1.6 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.4 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.6 s)
PASS  K4  Location scan: 6 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/map.service.spec.ts (moved to server/src/modules/map/map.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/map.repository.ts (moved to server/src/modules/map/map.repository.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.5 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:c7010d48a6087c57c6957d620d7fbcf20fe586bb1227e0574b71752ee67bc120
017 R1 module/memory certified 6 files moved, 18 specifier edits in 15 files, 1 m 28 s

Commit 997aa6197796b20170ea241200c861598d982244, tree be8c458f1124dcb9e57030695c6a4ef12ead03a0

6 paths moved
server/src/controllers/memory.controller.spec.ts
  → server/src/modules/memory/memory.controller.spec.ts
server/src/controllers/memory.controller.ts
  → server/src/modules/memory/memory.controller.ts
server/src/dtos/memory.dto.ts
  → server/src/modules/memory/memory.dto.ts
server/src/repositories/memory.repository.ts
  → server/src/modules/memory/memory.repository.ts
server/src/services/memory.service.spec.ts
  → server/src/modules/memory/memory.service.spec.ts
server/src/services/memory.service.ts
  → server/src/modules/memory/memory.service.ts

attempt 1: passed round 1, from 07eedaa5ee, 6 moves, 1 m 28 s

Certificate: PASS (static checks) certificates/017-R1-module-memory.json

certificate JSON · digest sha256:635253430a5334005f89634284094c8951ea874265d3dc97bc686b66e2a41f37

ac certify 07eedaa5ee..fa7a0168e8 (package root server/), profile immich
trees: fdcdfa4860..be8c458f11
pathMap: 6 moves, 10 edited in place, 3448 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 6 moved files (5.1 s)
PASS  K1  Move-set integrity: 6 moves, 10 files edited in place, nothing added or deleted (1.9 s)
PASS  K2  Byte-span confinement: 18 specifier spans changed in 15 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 18 rewritten specifiers keep their form (1.6 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.6 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.7 s)
PASS  K4  Location scan: 6 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.2 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/memory.service.spec.ts (moved to server/src/modules/memory/memory.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/memory.repository.ts (moved to server/src/modules/memory/memory.repository.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (47.7 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:635253430a5334005f89634284094c8951ea874265d3dc97bc686b66e2a41f37
018 R1 module/notification certified 12 files moved, 35 specifier edits in 21 files, 1 m 28 s

Commit 4e035e7be119fa8b6c80beda2f4fc8076ceaa6e0, tree 41fd829013c82d625da879b9ba2dd90dcdd1a6ad

12 paths moved
server/src/controllers/notification-admin.controller.spec.ts
  → server/src/modules/notification/notification-admin.controller.spec.ts
server/src/controllers/notification-admin.controller.ts
  → server/src/modules/notification/notification-admin.controller.ts
server/src/controllers/notification.controller.spec.ts
  → server/src/modules/notification/notification.controller.spec.ts
server/src/controllers/notification.controller.ts
  → server/src/modules/notification/notification.controller.ts
server/src/dtos/notification.dto.ts
  → server/src/modules/notification/notification.dto.ts
server/src/repositories/email.repository.spec.ts
  → server/src/modules/notification/email.repository.spec.ts
server/src/repositories/email.repository.ts
  → server/src/modules/notification/email.repository.ts
server/src/repositories/notification.repository.ts
  → server/src/modules/notification/notification.repository.ts
server/src/services/notification-admin.service.spec.ts
  → server/src/modules/notification/notification-admin.service.spec.ts
server/src/services/notification-admin.service.ts
  → server/src/modules/notification/notification-admin.service.ts
server/src/services/notification.service.spec.ts
  → server/src/modules/notification/notification.service.spec.ts
server/src/services/notification.service.ts
  → server/src/modules/notification/notification.service.ts

attempt 1: passed round 1, from 997aa61977, 12 moves, 1 m 28 s

Certificate: PASS (static checks) certificates/018-R1-module-notification.json

certificate JSON · digest sha256:df5c32a7fd428f1a013c3961c5c399c4f3b059a1df98110de55550b017a1fa08

ac certify 997aa61977..47e5054c64 (package root server/), profile immich
trees: be8c458f11..41fd829013
pathMap: 12 moves, 11 edited in place, 3441 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 12 moved files (5.1 s)
PASS  K1  Move-set integrity: 12 moves, 11 files edited in place, nothing added or deleted (2.0 s)
PASS  K2  Byte-span confinement: 35 specifier spans changed in 21 files; every other byte identical (0.8 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 35 rewritten specifiers keep their form (1.6 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.4 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.7 s)
PASS  K4  Location scan: 12 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.2 s)
        finding (stack-text) server/src/services/notification.service.ts: moved to server/src/modules/notification/notification.service.ts; 2 stack-trace reads passed along as text (line 88); their frames now name the new path
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/notification-admin.service.spec.ts (moved to server/src/modules/notification/notification-admin.service.spec.ts)
        … 7 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (47.9 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:df5c32a7fd428f1a013c3961c5c399c4f3b059a1df98110de55550b017a1fa08
019 R1 module/ocr certified 4 files moved, 17 specifier edits in 16 files, 1 m 29 s

Commit c96964ae28d71253902e0a096f1157b43a68db93, tree 8f6da4afe67068fc8f5f0ad934423bab32b64d4d

4 paths moved
server/src/dtos/ocr.dto.ts
  → server/src/modules/ocr/ocr.dto.ts
server/src/repositories/ocr.repository.ts
  → server/src/modules/ocr/ocr.repository.ts
server/src/services/ocr.service.spec.ts
  → server/src/modules/ocr/ocr.service.spec.ts
server/src/services/ocr.service.ts
  → server/src/modules/ocr/ocr.service.ts

attempt 1: passed round 1, from 4e035e7be1, 4 moves, 1 m 29 s

Certificate: PASS (static checks) certificates/019-R1-module-ocr.json

certificate JSON · digest sha256:e809b3f2a5fb91e6617fb6bbda1b981bb3c9eac7844a0680c1567d27299f9ded

ac certify 4e035e7be1..aba51162b7 (package root server/), profile immich
trees: 41fd829013..8f6da4afe6
pathMap: 4 moves, 14 edited in place, 3446 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 4 moved files (5.1 s)
PASS  K1  Move-set integrity: 4 moves, 14 files edited in place, nothing added or deleted (1.9 s)
PASS  K2  Byte-span confinement: 17 specifier spans changed in 16 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 17 rewritten specifiers keep their form (1.6 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.0 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.7 s)
PASS  K4  Location scan: 4 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (7 findings in docs, comments or ungated coverage settings) (5.2 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/ocr.service.spec.ts (moved to server/src/modules/ocr/ocr.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/ocr.repository.ts (moved to server/src/modules/ocr/ocr.repository.ts)
        … 5 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.0 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:e809b3f2a5fb91e6617fb6bbda1b981bb3c9eac7844a0680c1567d27299f9ded
020 R1 module/partner certified 6 files moved, 23 specifier edits in 19 files, 1 m 28 s

Commit ac92795533a878925c2c2259279b902a09e2afe5, tree f3720ee28842f1920d53b755c2f1a1fabd590a86

6 paths moved
server/src/controllers/partner.controller.spec.ts
  → server/src/modules/partner/partner.controller.spec.ts
server/src/controllers/partner.controller.ts
  → server/src/modules/partner/partner.controller.ts
server/src/dtos/partner.dto.ts
  → server/src/modules/partner/partner.dto.ts
server/src/repositories/partner.repository.ts
  → server/src/modules/partner/partner.repository.ts
server/src/services/partner.service.spec.ts
  → server/src/modules/partner/partner.service.spec.ts
server/src/services/partner.service.ts
  → server/src/modules/partner/partner.service.ts

attempt 1: passed round 1, from c96964ae28, 6 moves, 1 m 28 s

Certificate: PASS (static checks) certificates/020-R1-module-partner.json

certificate JSON · digest sha256:41ce2ac126760b58f8f5dcabbdebd7f03387a538d2c29c448db6fd0771747909

ac certify c96964ae28..38717d35e0 (package root server/), profile immich
trees: 8f6da4afe6..f3720ee288
pathMap: 6 moves, 15 edited in place, 3443 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 6 moved files (5.1 s)
PASS  K1  Move-set integrity: 6 moves, 15 files edited in place, nothing added or deleted (2.0 s)
PASS  K2  Byte-span confinement: 23 specifier spans changed in 19 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 23 rewritten specifiers keep their form (1.6 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.6 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.8 s)
PASS  K4  Location scan: 6 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.2 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/partner.service.spec.ts (moved to server/src/modules/partner/partner.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/partner.repository.ts (moved to server/src/modules/partner/partner.repository.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (47.7 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:41ce2ac126760b58f8f5dcabbdebd7f03387a538d2c29c448db6fd0771747909
021 R1 module/person certified 8 files moved, 52 specifier edits in 31 files, 1 m 28 s

Commit f46d651d904f1ba553e7eef6deeb1177781a5f19, tree 07ad191dc97ed965994764170d43bc38c7680a63

8 paths moved
server/src/controllers/face.controller.ts
  → server/src/modules/person/face.controller.ts
server/src/controllers/person.controller.spec.ts
  → server/src/modules/person/person.controller.spec.ts
server/src/controllers/person.controller.ts
  → server/src/modules/person/person.controller.ts
server/src/dtos/person.dto.ts
  → server/src/modules/person/person.dto.ts
server/src/repositories/person-user.repository.ts
  → server/src/modules/person/person-user.repository.ts
server/src/repositories/person.repository.ts
  → server/src/modules/person/person.repository.ts
server/src/services/person.service.spec.ts
  → server/src/modules/person/person.service.spec.ts
server/src/services/person.service.ts
  → server/src/modules/person/person.service.ts

attempt 1: passed round 1, from ac92795533, 8 moves, 1 m 28 s

Certificate: PASS (static checks) certificates/021-R1-module-person.json

certificate JSON · digest sha256:b0b2ada7c863eebb10aa86da6d06a4f3ba702874909ec9122f31866141167bb3

ac certify ac92795533..54af14b759 (package root server/), profile immich
trees: f3720ee288..07ad191dc9
pathMap: 8 moves, 24 edited in place, 3432 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 8 moved files (5.1 s)
PASS  K1  Move-set integrity: 8 moves, 24 files edited in place, nothing added or deleted (2.0 s)
PASS  K2  Byte-span confinement: 52 specifier spans changed in 31 files; every other byte identical (0.8 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 52 rewritten specifiers keep their form (1.6 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.4 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.6 s)
PASS  K4  Location scan: 8 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (stack-text) server/src/services/person.service.ts: moved to server/src/modules/person/person.service.ts; 2 stack-trace reads passed along as text (line 321); their frames now name the new path
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/person.service.spec.ts (moved to server/src/modules/person/person.service.spec.ts)
        … 7 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (47.7 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:b0b2ada7c863eebb10aa86da6d06a4f3ba702874909ec9122f31866141167bb3
022 R1 module/plugin certified 7 files moved, 24 specifier edits in 20 files, 1 m 29 s

Commit f22cfdafe13ebf9ee14ad454ed819b1b7e825efd, tree 53a3f1e592812f05944b673a8473eae4695511ef

7 paths moved
server/src/controllers/plugin.controller.spec.ts
  → server/src/modules/plugin/plugin.controller.spec.ts
server/src/controllers/plugin.controller.ts
  → server/src/modules/plugin/plugin.controller.ts
server/src/dtos/json-schema.dto.ts
  → server/src/modules/plugin/json-schema.dto.ts
server/src/dtos/plugin-manifest.dto.ts
  → server/src/modules/plugin/plugin-manifest.dto.ts
server/src/dtos/plugin.dto.ts
  → server/src/modules/plugin/plugin.dto.ts
server/src/repositories/plugin.repository.ts
  → server/src/modules/plugin/plugin.repository.ts
server/src/services/plugin.service.ts
  → server/src/modules/plugin/plugin.service.ts

attempt 1: passed round 1, from f46d651d90, 7 moves, 1 m 29 s

Certificate: PASS (static checks) certificates/022-R1-module-plugin.json

certificate JSON · digest sha256:770eaff65c77e904901a4a7a9847c59e78e0aab4e1892ea88ef186fa6f439b1e

ac certify f46d651d90..09bbf50bbe (package root server/), profile immich
trees: 07ad191dc9..53a3f1e592
pathMap: 7 moves, 14 edited in place, 3443 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 7 moved files (5.1 s)
PASS  K1  Move-set integrity: 7 moves, 14 files edited in place, nothing added or deleted (2.0 s)
PASS  K2  Byte-span confinement: 24 specifier spans changed in 20 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 24 rewritten specifiers keep their form (1.6 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.8 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.7 s)
PASS  K4  Location scan: 7 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (7 findings in docs, comments or ungated coverage settings) (5.1 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/plugin.service.ts (moved to server/src/modules/plugin/plugin.service.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/plugin.repository.ts (moved to server/src/modules/plugin/plugin.repository.ts)
        … 5 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.8 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:770eaff65c77e904901a4a7a9847c59e78e0aab4e1892ea88ef186fa6f439b1e
023 R1 module/queue certified 5 files moved, 15 specifier edits in 11 files, 1 m 28 s

Commit 647ede7d77c3986d2dbe5715f714848bf1205a24, tree 6fb8c8ea174210fc0dbe222e2a23837b94b08bb6

5 paths moved
server/src/controllers/queue.controller.ts
  → server/src/modules/queue/queue.controller.ts
server/src/dtos/queue-legacy.dto.ts
  → server/src/modules/queue/queue-legacy.dto.ts
server/src/dtos/queue.dto.ts
  → server/src/modules/queue/queue.dto.ts
server/src/services/queue.service.spec.ts
  → server/src/modules/queue/queue.service.spec.ts
server/src/services/queue.service.ts
  → server/src/modules/queue/queue.service.ts

attempt 1: passed round 1, from f22cfdafe1, 5 moves, 1 m 28 s

Certificate: PASS (static checks) certificates/023-R1-module-queue.json

certificate JSON · digest sha256:4d1451593104e43189095a261046555c59a308efc7adbb50924315aa7e5ba497

ac certify f22cfdafe1..8cc6af93f1 (package root server/), profile immich
trees: 53a3f1e592..6fb8c8ea17
pathMap: 5 moves, 7 edited in place, 3452 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 5 moved files (5.2 s)
PASS  K1  Move-set integrity: 5 moves, 7 files edited in place, nothing added or deleted (2.0 s)
PASS  K2  Byte-span confinement: 15 specifier spans changed in 11 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 15 rewritten specifiers keep their form (1.6 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.7 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.6 s)
PASS  K4  Location scan: 5 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (6 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/queue.service.spec.ts (moved to server/src/modules/queue/queue.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/queue.service.spec.ts (moved to server/src/modules/queue/queue.service.spec.ts)
        … 4 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.2 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:4d1451593104e43189095a261046555c59a308efc7adbb50924315aa7e5ba497
024 R1 module/search certified 12 files moved, 30 specifier edits in 19 files, 1 m 32 s

Commit 19194fde7a3b6046822206a0d01564bb1a7c5a8a, tree ff3a6f8e15d85907ac3841d75cff36c0b1013263

12 paths moved
server/src/controllers/search.controller.spec.ts
  → server/src/modules/search/search.controller.spec.ts
server/src/controllers/search.controller.ts
  → server/src/modules/search/search.controller.ts
server/src/dtos/search.dto.ts
  → server/src/modules/search/search.dto.ts
server/src/repositories/search.repository.ts
  → server/src/modules/search/search.repository.ts
server/src/services/search.service.spec.ts
  → server/src/modules/search/search.service.spec.ts
server/src/services/search.service.ts
  → server/src/modules/search/search.service.ts
server/src/services/smart-info.service.spec.ts
  → server/src/modules/search/smart-info.service.spec.ts
server/src/services/smart-info.service.ts
  → server/src/modules/search/smart-info.service.ts
server/src/utils/search-cursor.spec.ts
  → server/src/modules/search/search-cursor.spec.ts
server/src/utils/search-cursor.ts
  → server/src/modules/search/search-cursor.ts
server/src/utils/search-filter.spec.ts
  → server/src/modules/search/search-filter.spec.ts
server/src/utils/search-filter.ts
  → server/src/modules/search/search-filter.ts

attempt 1: passed round 1, from 647ede7d77, 12 moves, 1 m 32 s

Certificate: PASS (static checks) certificates/024-R1-module-search.json

certificate JSON · digest sha256:265a27a32e24e31750f7adf0deb62d56601cb91b6f4d81f11f603c114c1b98db

ac certify 647ede7d77..5bb36e6543 (package root server/), profile immich
trees: 6fb8c8ea17..ff3a6f8e15
pathMap: 12 moves, 10 edited in place, 3442 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 12 moved files (5.3 s)
PASS  K1  Move-set integrity: 12 moves, 10 files edited in place, nothing added or deleted (2.3 s)
PASS  K2  Byte-span confinement: 30 specifier spans changed in 19 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 30 rewritten specifiers keep their form (1.6 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.7 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (7.0 s)
PASS  K4  Location scan: 12 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (9 findings in docs, comments or ungated coverage settings) (5.4 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/search.service.spec.ts (moved to server/src/modules/search/search.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/search.repository.ts (moved to server/src/modules/search/search.repository.ts)
        … 7 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.5 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:265a27a32e24e31750f7adf0deb62d56601cb91b6f4d81f11f603c114c1b98db
025 R1 module/server certified 5 files moved, 15 specifier edits in 12 files, 1 m 30 s

Commit 4b1f6d4a3f8b7c9bcfde7925d9ccc0ada3ac21f5, tree d72c2af01678b138785dfe2f491df02db82aa7f3

5 paths moved
server/src/controllers/server.controller.ts
  → server/src/modules/server/server.controller.ts
server/src/dtos/server.dto.ts
  → server/src/modules/server/server.dto.ts
server/src/repositories/server-info.repository.ts
  → server/src/modules/server/server-info.repository.ts
server/src/services/server.service.spec.ts
  → server/src/modules/server/server.service.spec.ts
server/src/services/server.service.ts
  → server/src/modules/server/server.service.ts

attempt 1: passed round 1, from 19194fde7a, 5 moves, 1 m 30 s

Certificate: PASS (static checks) certificates/025-R1-module-server.json

certificate JSON · digest sha256:545f662ce944a51329a1decb935b765019fa3058699210d475530e7720e9f826

ac certify 19194fde7a..78aa204424 (package root server/), profile immich
trees: ff3a6f8e15..d72c2af016
pathMap: 5 moves, 9 edited in place, 3450 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 5 moved files (5.2 s)
PASS  K1  Move-set integrity: 5 moves, 9 files edited in place, nothing added or deleted (2.3 s)
PASS  K2  Byte-span confinement: 15 specifier spans changed in 12 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 15 rewritten specifiers keep their form (1.6 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.3 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.9 s)
PASS  K4  Location scan: 5 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/server.service.spec.ts (moved to server/src/modules/server/server.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/server-info.repository.ts (moved to server/src/modules/server/server-info.repository.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.5 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:545f662ce944a51329a1decb935b765019fa3058699210d475530e7720e9f826
026 R1 module/session certified 5 files moved, 14 specifier edits in 13 files, 1 m 28 s

Commit f52a272a087697b9a3514969a5b95c6b517cbdb6, tree 91f8dd59f7ac4588dabee2f5d33e45212b67d4d8

5 paths moved
server/src/controllers/session.controller.ts
  → server/src/modules/session/session.controller.ts
server/src/dtos/session.dto.ts
  → server/src/modules/session/session.dto.ts
server/src/repositories/session.repository.ts
  → server/src/modules/session/session.repository.ts
server/src/services/session.service.spec.ts
  → server/src/modules/session/session.service.spec.ts
server/src/services/session.service.ts
  → server/src/modules/session/session.service.ts

attempt 1: passed round 1, from 4b1f6d4a3f, 5 moves, 1 m 28 s

Certificate: PASS (static checks) certificates/026-R1-module-session.json

certificate JSON · digest sha256:cf929b5b12f8ced24cb07c16287d6e23be3f922f3adafb4e7ee43b8bf9c2014d

ac certify 4b1f6d4a3f..5e9bbade20 (package root server/), profile immich
trees: d72c2af016..91f8dd59f7
pathMap: 5 moves, 10 edited in place, 3449 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 5 moved files (5.1 s)
PASS  K1  Move-set integrity: 5 moves, 10 files edited in place, nothing added or deleted (2.1 s)
PASS  K2  Byte-span confinement: 14 specifier spans changed in 13 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 14 rewritten specifiers keep their form (1.6 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.6 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.7 s)
PASS  K4  Location scan: 5 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/session.service.spec.ts (moved to server/src/modules/session/session.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/session.repository.ts (moved to server/src/modules/session/session.repository.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.0 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:cf929b5b12f8ced24cb07c16287d6e23be3f922f3adafb4e7ee43b8bf9c2014d
027 R1 module/shared-link certified 7 files moved, 25 specifier edits in 15 files, 1 m 31 s

Commit 8a0796ea65964c2fb89fd016a002de34ab6f8a74, tree 38a555880f940a9bf7d28d7233cccc9bf31ca4da

7 paths moved
server/src/controllers/shared-link.controller.spec.ts
  → server/src/modules/shared-link/shared-link.controller.spec.ts
server/src/controllers/shared-link.controller.ts
  → server/src/modules/shared-link/shared-link.controller.ts
server/src/dtos/shared-link.dto.ts
  → server/src/modules/shared-link/shared-link.dto.ts
server/src/repositories/shared-link-asset.repository.ts
  → server/src/modules/shared-link/shared-link-asset.repository.ts
server/src/repositories/shared-link.repository.ts
  → server/src/modules/shared-link/shared-link.repository.ts
server/src/services/shared-link.service.spec.ts
  → server/src/modules/shared-link/shared-link.service.spec.ts
server/src/services/shared-link.service.ts
  → server/src/modules/shared-link/shared-link.service.ts

attempt 1: passed round 1, from f52a272a08, 7 moves, 1 m 31 s

Certificate: PASS (static checks) certificates/027-R1-module-shared-link.json

certificate JSON · digest sha256:564f26960da4fc42577cb267598a06a8502d232a574d7b355ea3d079d63cde1b

ac certify f52a272a08..3a6ae826d5 (package root server/), profile immich
trees: 91f8dd59f7..38a555880f
pathMap: 7 moves, 11 edited in place, 3446 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 7 moved files (5.2 s)
PASS  K1  Move-set integrity: 7 moves, 11 files edited in place, nothing added or deleted (2.3 s)
PASS  K2  Byte-span confinement: 25 specifier spans changed in 15 files; every other byte identical (0.8 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 25 rewritten specifiers keep their form (1.7 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.2 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.8 s)
PASS  K4  Location scan: 7 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.7 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/shared-link.service.spec.ts (moved to server/src/modules/shared-link/shared-link.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/shared-link-asset.repository.ts (moved to server/src/modules/shared-link/shared-link-asset.repository.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.5 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:564f26960da4fc42577cb267598a06a8502d232a574d7b355ea3d079d63cde1b
028 R1 module/stack certified 6 files moved, 17 specifier edits in 14 files, 1 m 31 s

Commit e6dd9c9e329a5dcb073b2bca9b8cce621ed730f6, tree 7d27e1fdd2e02ecef417e3877b1d14496b470412

6 paths moved
server/src/controllers/stack.controller.spec.ts
  → server/src/modules/stack/stack.controller.spec.ts
server/src/controllers/stack.controller.ts
  → server/src/modules/stack/stack.controller.ts
server/src/dtos/stack.dto.ts
  → server/src/modules/stack/stack.dto.ts
server/src/repositories/stack.repository.ts
  → server/src/modules/stack/stack.repository.ts
server/src/services/stack.service.spec.ts
  → server/src/modules/stack/stack.service.spec.ts
server/src/services/stack.service.ts
  → server/src/modules/stack/stack.service.ts

attempt 1: passed round 1, from 8a0796ea65, 6 moves, 1 m 31 s

Certificate: PASS (static checks) certificates/028-R1-module-stack.json

certificate JSON · digest sha256:bb1ddf305defe37d815400fcb5db5e0eec282b2e52799f0c2898b0a7aa6b173a

ac certify 8a0796ea65..3158cf0975 (package root server/), profile immich
trees: 38a555880f..7d27e1fdd2
pathMap: 6 moves, 10 edited in place, 3448 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 6 moved files (5.3 s)
PASS  K1  Move-set integrity: 6 moves, 10 files edited in place, nothing added or deleted (2.1 s)
PASS  K2  Byte-span confinement: 17 specifier spans changed in 14 files; every other byte identical (0.8 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 17 rewritten specifiers keep their form (1.7 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.5 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.7 s)
PASS  K4  Location scan: 6 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.4 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/stack.service.spec.ts (moved to server/src/modules/stack/stack.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/stack.repository.ts (moved to server/src/modules/stack/stack.repository.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.9 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:bb1ddf305defe37d815400fcb5db5e0eec282b2e52799f0c2898b0a7aa6b173a
029 R1 module/sync certified 8 files moved, 28 specifier edits in 16 files, 1 m 31 s

Commit 6c6c7beb83d0721371fa28dd4bb477f84c29fc5f, tree e937e8201a4729d1b594a5528639100355b5650b

8 paths moved
server/src/controllers/sync.controller.spec.ts
  → server/src/modules/sync/sync.controller.spec.ts
server/src/controllers/sync.controller.ts
  → server/src/modules/sync/sync.controller.ts
server/src/dtos/sync.dto.ts
  → server/src/modules/sync/sync.dto.ts
server/src/repositories/sync-checkpoint.repository.ts
  → server/src/modules/sync/sync-checkpoint.repository.ts
server/src/repositories/sync.repository.ts
  → server/src/modules/sync/sync.repository.ts
server/src/services/sync.service.spec.ts
  → server/src/modules/sync/sync.service.spec.ts
server/src/services/sync.service.ts
  → server/src/modules/sync/sync.service.ts
server/src/utils/sync.ts
  → server/src/modules/sync/sync.ts

attempt 1: passed round 1, from e6dd9c9e32, 8 moves, 1 m 31 s

Certificate: PASS (static checks) certificates/029-R1-module-sync.json

certificate JSON · digest sha256:97f130ff95d11c84a28986f4b7c06e126809f22be573119a9606dec266ea2819

ac certify e6dd9c9e32..db4d2eef6a (package root server/), profile immich
trees: 7d27e1fdd2..e937e8201a
pathMap: 8 moves, 11 edited in place, 3445 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 8 moved files (5.2 s)
PASS  K1  Move-set integrity: 8 moves, 11 files edited in place, nothing added or deleted (2.0 s)
PASS  K2  Byte-span confinement: 28 specifier spans changed in 16 files; every other byte identical (0.8 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 28 rewritten specifiers keep their form (1.7 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.7 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.7 s)
PASS  K4  Location scan: 8 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (9 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/sync.service.spec.ts (moved to server/src/modules/sync/sync.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/sync-checkpoint.repository.ts (moved to server/src/modules/sync/sync-checkpoint.repository.ts)
        … 7 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (50.0 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:97f130ff95d11c84a28986f4b7c06e126809f22be573119a9606dec266ea2819
030 R1 module/system-metadata certified 7 files moved, 33 specifier edits in 30 files, 1 m 31 s

Commit d087b024ebcf22326d58ac5f034b15322c5d77b4, tree ffe63678445db4d6f8e981f32ca38f34bff4bec5

7 paths moved
server/src/controllers/system-metadata.controller.spec.ts
  → server/src/modules/system-metadata/system-metadata.controller.spec.ts
server/src/controllers/system-metadata.controller.ts
  → server/src/modules/system-metadata/system-metadata.controller.ts
server/src/dtos/onboarding.dto.ts
  → server/src/modules/system-metadata/onboarding.dto.ts
server/src/dtos/system-metadata.dto.ts
  → server/src/modules/system-metadata/system-metadata.dto.ts
server/src/repositories/system-metadata.repository.ts
  → server/src/modules/system-metadata/system-metadata.repository.ts
server/src/services/system-metadata.service.spec.ts
  → server/src/modules/system-metadata/system-metadata.service.spec.ts
server/src/services/system-metadata.service.ts
  → server/src/modules/system-metadata/system-metadata.service.ts

attempt 1: passed round 1, from 6c6c7beb83, 7 moves, 1 m 31 s

Certificate: PASS (static checks) certificates/030-R1-module-system-metadata.json

certificate JSON · digest sha256:a5c2078b5921fa3c2180cef828dd8176561c515469d6b6a78b2853618b9b63cf

ac certify 6c6c7beb83..98a5b5415f (package root server/), profile immich
trees: e937e8201a..ffe6367844
pathMap: 7 moves, 26 edited in place, 3431 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 7 moved files (5.4 s)
PASS  K1  Move-set integrity: 7 moves, 26 files edited in place, nothing added or deleted (2.2 s)
PASS  K2  Byte-span confinement: 33 specifier spans changed in 30 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 33 rewritten specifiers keep their form (1.7 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.8 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.8 s)
PASS  K4  Location scan: 7 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.4 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/system-metadata.service.spec.ts (moved to server/src/modules/system-metadata/system-metadata.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/system-metadata.repository.ts (moved to server/src/modules/system-metadata/system-metadata.repository.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.1 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:a5c2078b5921fa3c2180cef828dd8176561c515469d6b6a78b2853618b9b63cf
031 R1 module/tag certified 8 files moved, 28 specifier edits in 22 files, 1 m 31 s

Commit 472518957e22f4911a81b93f61efcca4dd4c8b78, tree 2af2dcb65cc69f90778d5cdc9e50f5fd26b9e9ad

8 paths moved
server/src/controllers/tag.controller.spec.ts
  → server/src/modules/tag/tag.controller.spec.ts
server/src/controllers/tag.controller.ts
  → server/src/modules/tag/tag.controller.ts
server/src/dtos/tag.dto.ts
  → server/src/modules/tag/tag.dto.ts
server/src/repositories/tag.repository.ts
  → server/src/modules/tag/tag.repository.ts
server/src/services/tag.service.spec.ts
  → server/src/modules/tag/tag.service.spec.ts
server/src/services/tag.service.ts
  → server/src/modules/tag/tag.service.ts
server/src/utils/replace-template-tags.ts
  → server/src/modules/tag/replace-template-tags.ts
server/src/utils/tag.ts
  → server/src/modules/tag/tag.ts

attempt 1: passed round 1, from d087b024eb, 8 moves, 1 m 31 s

Certificate: PASS (static checks) certificates/031-R1-module-tag.json

certificate JSON · digest sha256:f6df30cfeabd80c7c495f764dcf020090ef3150760bd48b94d5a0546d722723e

ac certify d087b024eb..1e96625d19 (package root server/), profile immich
trees: ffe6367844..2af2dcb65c
pathMap: 8 moves, 17 edited in place, 3439 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 8 moved files (5.2 s)
PASS  K1  Move-set integrity: 8 moves, 17 files edited in place, nothing added or deleted (2.2 s)
PASS  K2  Byte-span confinement: 28 specifier spans changed in 22 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 28 rewritten specifiers keep their form (1.7 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.3 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.9 s)
PASS  K4  Location scan: 8 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (9 findings in docs, comments or ungated coverage settings) (5.4 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/tag.service.spec.ts (moved to server/src/modules/tag/tag.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/tag.repository.ts (moved to server/src/modules/tag/tag.repository.ts)
        … 7 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.7 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:f6df30cfeabd80c7c495f764dcf020090ef3150760bd48b94d5a0546d722723e
032 R1 module/timeline certified 6 files moved, 10 specifier edits in 8 files, 1 m 29 s

Commit 4fa212f50fd4c45d09be22152b8047aa00d998dc, tree d22ff8be30f2efa6e4148869d25f359cb9e08169

6 paths moved
server/src/controllers/timeline.controller.spec.ts
  → server/src/modules/timeline/timeline.controller.spec.ts
server/src/controllers/timeline.controller.ts
  → server/src/modules/timeline/timeline.controller.ts
server/src/dtos/bbox.dto.ts
  → server/src/modules/timeline/bbox.dto.ts
server/src/dtos/time-bucket.dto.ts
  → server/src/modules/timeline/time-bucket.dto.ts
server/src/services/timeline.service.spec.ts
  → server/src/modules/timeline/timeline.service.spec.ts
server/src/services/timeline.service.ts
  → server/src/modules/timeline/timeline.service.ts

attempt 1: passed round 1, from 472518957e, 6 moves, 1 m 29 s

Certificate: PASS (static checks) certificates/032-R1-module-timeline.json

certificate JSON · digest sha256:9fa6c741377db1aacd398d2ce851cfa7ab2371a75a44e55c5cc1af565a99998a

ac certify 472518957e..8d6ccb9c20 (package root server/), profile immich
trees: 2af2dcb65c..d22ff8be30
pathMap: 6 moves, 3 edited in place, 3455 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 6 moved files (5.2 s)
PASS  K1  Move-set integrity: 6 moves, 3 files edited in place, nothing added or deleted (2.2 s)
PASS  K2  Byte-span confinement: 10 specifier spans changed in 8 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 10 rewritten specifiers keep their form (1.7 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.1 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.7 s)
PASS  K4  Location scan: 6 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (6 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/timeline.service.spec.ts (moved to server/src/modules/timeline/timeline.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/timeline.service.spec.ts (moved to server/src/modules/timeline/timeline.service.spec.ts)
        … 4 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.0 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:9fa6c741377db1aacd398d2ce851cfa7ab2371a75a44e55c5cc1af565a99998a
033 R1 module/trash certified 6 files moved, 11 specifier edits in 9 files, 1 m 29 s

Commit e3faa7670134cc0f23e68be62e479ad284bb2e3e, tree 9d839b19b3662c8284b824e10eafcb3c22f6c831

6 paths moved
server/src/controllers/trash.controller.spec.ts
  → server/src/modules/trash/trash.controller.spec.ts
server/src/controllers/trash.controller.ts
  → server/src/modules/trash/trash.controller.ts
server/src/dtos/trash.dto.ts
  → server/src/modules/trash/trash.dto.ts
server/src/repositories/trash.repository.ts
  → server/src/modules/trash/trash.repository.ts
server/src/services/trash.service.spec.ts
  → server/src/modules/trash/trash.service.spec.ts
server/src/services/trash.service.ts
  → server/src/modules/trash/trash.service.ts

attempt 1: passed round 1, from 4fa212f50f, 6 moves, 1 m 29 s

Certificate: PASS (static checks) certificates/033-R1-module-trash.json

certificate JSON · digest sha256:4710fd16f9e24a9865c1ac66778fdb7e1e68e3af709b63c86e82756b289a3fc4

ac certify 4fa212f50f..556687fe73 (package root server/), profile immich
trees: d22ff8be30..9d839b19b3
pathMap: 6 moves, 5 edited in place, 3453 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 6 moved files (5.4 s)
PASS  K1  Move-set integrity: 6 moves, 5 files edited in place, nothing added or deleted (1.9 s)
PASS  K2  Byte-span confinement: 11 specifier spans changed in 9 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 11 rewritten specifiers keep their form (1.7 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.7 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.6 s)
PASS  K4  Location scan: 6 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.2 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/trash.service.spec.ts (moved to server/src/modules/trash/trash.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/trash.repository.ts (moved to server/src/modules/trash/trash.repository.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.0 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:4710fd16f9e24a9865c1ac66778fdb7e1e68e3af709b63c86e82756b289a3fc4
034 R1 module/user certified 19 files moved, 84 specifier edits in 55 files, 1 m 34 s

Commit 7f6655d9b022638dbf63d4e23784dfb2df9e0b84, tree d422259252f5e0102c64f5c02023472ff89f73ec

19 paths moved
server/src/commands/list-users.command.ts
  → server/src/modules/user/list-users.command.ts
server/src/commands/reset-admin-password.command.ts
  → server/src/modules/user/reset-admin-password.command.ts
server/src/controllers/user-admin.controller.spec.ts
  → server/src/modules/user/user-admin.controller.spec.ts
server/src/controllers/user-admin.controller.ts
  → server/src/modules/user/user-admin.controller.ts
server/src/controllers/user.controller.spec.ts
  → server/src/modules/user/user.controller.spec.ts
server/src/controllers/user.controller.ts
  → server/src/modules/user/user.controller.ts
server/src/dtos/calendar-heatmap.dto.ts
  → server/src/modules/user/calendar-heatmap.dto.ts
server/src/dtos/license.dto.ts
  → server/src/modules/user/license.dto.ts
server/src/dtos/user-preferences.dto.ts
  → server/src/modules/user/user-preferences.dto.ts
server/src/dtos/user-profile.dto.ts
  → server/src/modules/user/user-profile.dto.ts
server/src/dtos/user.dto.spec.ts
  → server/src/modules/user/user.dto.spec.ts
server/src/dtos/user.dto.ts
  → server/src/modules/user/user.dto.ts
server/src/repositories/user.repository.ts
  → server/src/modules/user/user.repository.ts
server/src/services/shared/user-methods.ts
  → server/src/modules/user/user-methods.ts
server/src/services/user-admin.service.spec.ts
  → server/src/modules/user/user-admin.service.spec.ts
server/src/services/user-admin.service.ts
  → server/src/modules/user/user-admin.service.ts
server/src/services/user.service.spec.ts
  → server/src/modules/user/user.service.spec.ts
server/src/services/user.service.ts
  → server/src/modules/user/user.service.ts
server/src/utils/profile-image.ts
  → server/src/modules/user/profile-image.ts

attempt 1: passed round 1, from e3faa76701, 19 moves, 1 m 34 s

Certificate: PASS (static checks) certificates/034-R1-module-user.json

certificate JSON · digest sha256:05d6528809e72a363a08f80dc87ae32466c76c6b7d21ce65ddadd5cb0719f37b

ac certify e3faa76701..64bf31b18e (package root server/), profile immich
trees: 9d839b19b3..d422259252
pathMap: 19 moves, 43 edited in place, 3402 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 19 moved files (5.2 s)
PASS  K1  Move-set integrity: 19 moves, 43 files edited in place, nothing added or deleted (2.1 s)
PASS  K2  Byte-span confinement: 84 specifier spans changed in 55 files; every other byte identical (0.9 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 84 rewritten specifiers keep their form (1.7 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.7 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (7.5 s)
PASS  K4  Location scan: 19 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (9 findings in docs, comments or ungated coverage settings) (5.6 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/shared/user-methods.ts (moved to server/src/modules/user/user-methods.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/user.repository.ts (moved to server/src/modules/user/user.repository.ts)
        … 7 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (51.0 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:05d6528809e72a363a08f80dc87ae32466c76c6b7d21ce65ddadd5cb0719f37b
035 R1 module/version certified 4 files moved, 12 specifier edits in 11 files, 1 m 33 s

Commit e6dcb6a202a2b868d6653b4a311b621d901ec637, tree 2b7c2760ac74c0da8e6c07c99173f6620957cbfd

4 paths moved
server/src/commands/version.command.ts
  → server/src/modules/version/version.command.ts
server/src/repositories/version-history.repository.ts
  → server/src/modules/version/version-history.repository.ts
server/src/services/version.service.spec.ts
  → server/src/modules/version/version.service.spec.ts
server/src/services/version.service.ts
  → server/src/modules/version/version.service.ts

attempt 1: passed round 1, from 7f6655d9b0, 4 moves, 1 m 33 s

Certificate: PASS (static checks) certificates/035-R1-module-version.json

certificate JSON · digest sha256:5e90d7f6c804818b780d9aa42d3362a36c03d170efa4c97d145381f9808090f6

ac certify 7f6655d9b0..efd50f92bf (package root server/), profile immich
trees: d422259252..2b7c2760ac
pathMap: 4 moves, 9 edited in place, 3451 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 4 moved files (5.3 s)
PASS  K1  Move-set integrity: 4 moves, 9 files edited in place, nothing added or deleted (2.2 s)
PASS  K2  Byte-span confinement: 12 specifier spans changed in 11 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 12 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.7 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.7 s)
PASS  K4  Location scan: 4 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (7 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (stack-text) server/src/services/version.service.ts: moved to server/src/modules/version/version.service.ts; 1 stack-trace reads passed along as text (line 140); their frames now name the new path
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/version.service.spec.ts (moved to server/src/modules/version/version.service.spec.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (50.8 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:5e90d7f6c804818b780d9aa42d3362a36c03d170efa4c97d145381f9808090f6
036 R1 module/video-stream certified 5 files moved, 8 specifier edits in 7 files, 1 m 31 s

Commit 311549fdac8d226b3b2c4cb4dde607ef98a8f700, tree d074d7315073bf13f5381ba5bbd8f8369d671ec1

5 paths moved
server/src/controllers/video-stream.controller.ts
  → server/src/modules/video-stream/video-stream.controller.ts
server/src/dtos/streaming.dto.ts
  → server/src/modules/video-stream/streaming.dto.ts
server/src/repositories/video-stream.repository.ts
  → server/src/modules/video-stream/video-stream.repository.ts
server/src/services/hls.service.spec.ts
  → server/src/modules/video-stream/hls.service.spec.ts
server/src/services/hls.service.ts
  → server/src/modules/video-stream/hls.service.ts

attempt 1: passed round 1, from e6dcb6a202, 5 moves, 1 m 31 s

Certificate: PASS (static checks) certificates/036-R1-module-video-stream.json

certificate JSON · digest sha256:06e897d20ce18650a2e886cb584e97f6023f85aa54a406bd1e8909855ed62c8e

ac certify e6dcb6a202..e72c63b1ad (package root server/), profile immich
trees: 2b7c2760ac..d074d73150
pathMap: 5 moves, 5 edited in place, 3454 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 5 moved files (5.3 s)
PASS  K1  Move-set integrity: 5 moves, 5 files edited in place, nothing added or deleted (2.3 s)
PASS  K2  Byte-span confinement: 8 specifier spans changed in 7 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 8 rewritten specifiers keep their form (1.7 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.9 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.8 s)
PASS  K4  Location scan: 5 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/hls.service.spec.ts (moved to server/src/modules/video-stream/hls.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/video-stream.repository.ts (moved to server/src/modules/video-stream/video-stream.repository.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.0 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:06e897d20ce18650a2e886cb584e97f6023f85aa54a406bd1e8909855ed62c8e
037 R1 module/view certified 4 files moved, 7 specifier edits in 7 files, 1 m 32 s

Commit c8cd777f3808c7142d1c2d0171fb42d9ba63e1d5, tree 37262610ad710a9058ce0603a4ddc2159dcb7574

4 paths moved
server/src/controllers/view.controller.ts
  → server/src/modules/view/view.controller.ts
server/src/repositories/view-repository.ts
  → server/src/modules/view/view-repository.ts
server/src/services/view.service.spec.ts
  → server/src/modules/view/view.service.spec.ts
server/src/services/view.service.ts
  → server/src/modules/view/view.service.ts

attempt 1: passed round 1, from 311549fdac, 4 moves, 1 m 32 s

Certificate: PASS (static checks) certificates/037-R1-module-view.json

certificate JSON · digest sha256:7c78bd44ab7c9cb73d562697db85985547fe218c949b621ac27f0e92af56ca37

ac certify 311549fdac..37569c3162 (package root server/), profile immich
trees: d074d73150..37262610ad
pathMap: 4 moves, 5 edited in place, 3455 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 4 moved files (5.3 s)
PASS  K1  Move-set integrity: 4 moves, 5 files edited in place, nothing added or deleted (2.2 s)
PASS  K2  Byte-span confinement: 7 specifier spans changed in 7 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 7 rewritten specifiers keep their form (1.7 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.5 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.8 s)
PASS  K4  Location scan: 4 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.4 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/view.service.spec.ts (moved to server/src/modules/view/view.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/view-repository.ts (moved to server/src/modules/view/view-repository.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.8 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:7c78bd44ab7c9cb73d562697db85985547fe218c949b621ac27f0e92af56ca37
038 R1 module/workflow certified 8 files moved, 22 specifier edits in 15 files, 1 m 30 s

Commit 2f35e608a3b83efdf968d6610876f99bf3533fd1, tree eae80d417fdbc5614a990668aff2433c920c162f

8 paths moved
server/src/controllers/workflow.controller.spec.ts
  → server/src/modules/workflow/workflow.controller.spec.ts
server/src/controllers/workflow.controller.ts
  → server/src/modules/workflow/workflow.controller.ts
server/src/dtos/workflow.dto.ts
  → server/src/modules/workflow/workflow.dto.ts
server/src/repositories/workflow.repository.ts
  → server/src/modules/workflow/workflow.repository.ts
server/src/services/workflow-execution.service.ts
  → server/src/modules/workflow/workflow-execution.service.ts
server/src/services/workflow.service.ts
  → server/src/modules/workflow/workflow.service.ts
server/src/utils/workflow.spec.ts
  → server/src/modules/workflow/workflow.spec.ts
server/src/utils/workflow.ts
  → server/src/modules/workflow/workflow.ts

attempt 1: passed round 1, from c8cd777f38, 8 moves, 1 m 30 s

Certificate: PASS (static checks) certificates/038-R1-module-workflow.json

certificate JSON · digest sha256:87ea639f6470b33b21871816ac974e94eceb1e2f70ab6b10f105d1185226786d

ac certify c8cd777f38..83ebdb9bff (package root server/), profile immich
trees: 37262610ad..eae80d417f
pathMap: 8 moves, 10 edited in place, 3446 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 8 moved files (5.2 s)
PASS  K1  Move-set integrity: 8 moves, 10 files edited in place, nothing added or deleted (1.9 s)
PASS  K2  Byte-span confinement: 22 specifier spans changed in 15 files; every other byte identical (0.8 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 22 rewritten specifiers keep their form (1.7 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.2 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.6 s)
PASS  K4  Location scan: 8 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (stack-text) server/src/services/workflow-execution.service.ts: moved to server/src/modules/workflow/workflow-execution.service.ts; 1 stack-trace reads passed along as text (line 197); their frames now name the new path
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/workflow-execution.service.ts (moved to server/src/modules/workflow/workflow-execution.service.ts)
        … 7 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.2 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.6 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:87ea639f6470b33b21871816ac974e94eceb1e2f70ab6b10f105d1185226786d
039 R2 platform/access certified 3 files moved, 38 specifier edits in 35 files, 1 m 33 s

Commit a86f388bdfc4c28c07bf5de3cee587397c0ed8f0, tree 35c1ac1bea6c50941a1a9f9517dbd9a58b9ad9da

3 paths moved
server/src/repositories/access.repository.ts
  → server/src/platform/access/access.repository.ts
server/src/utils/access.ts
  → server/src/platform/access/access.ts
server/src/utils/set.ts
  → server/src/platform/access/set.ts

attempt 1: passed round 1, from 2f35e608a3, 3 moves, 1 m 33 s

Certificate: PASS (static checks) certificates/039-R2-platform-access.json

certificate JSON · digest sha256:5f9001a4548b37c2fc9bef0f1197e89780605f1fc30431f574eed462951a4576

ac certify 2f35e608a3..aef65f3fd9 (package root server/), profile immich
trees: eae80d417f..35c1ac1bea
pathMap: 3 moves, 34 edited in place, 3427 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 3 moved files (5.3 s)
PASS  K1  Move-set integrity: 3 moves, 34 files edited in place, nothing added or deleted (2.1 s)
PASS  K2  Byte-span confinement: 38 specifier spans changed in 35 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 38 rewritten specifiers keep their form (1.7 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.1 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (7.0 s)
PASS  K4  Location scan: 3 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (3 findings in docs, comments or ungated coverage settings) (5.5 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/access.repository.ts (moved to server/src/platform/access/access.repository.ts)
        finding (old-path-in-docs) docs/docs/developer/architecture.mdx: line 60: 'src/repositories' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/access.repository.ts (moved to server/src/platform/access/access.repository.ts)
        … 1 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (50.5 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.6 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:5f9001a4548b37c2fc9bef0f1197e89780605f1fc30431f574eed462951a4576
040 R2 platform/bootstrap certified 3 files moved, 4 specifier edits in 4 files, 1 m 32 s

Commit b38343f4aa5dbb7a072f7187cf04f28d433ca91d, tree 720d5b8fa671c668f556df07a1d1ca3e6f09c6ee

3 paths moved
server/src/app.common.ts
  → server/src/platform/bootstrap/app.common.ts
server/src/controllers/app.controller.spec.ts
  → server/src/platform/bootstrap/app.controller.spec.ts
server/src/controllers/app.controller.ts
  → server/src/platform/bootstrap/app.controller.ts

attempt 1: passed round 1, from a86f388bdf, 3 moves, 1 m 32 s

Certificate: PASS (static checks) certificates/040-R2-platform-bootstrap.json

certificate JSON · digest sha256:97af69aa161618d42c2e43f7b4231cf86d13e27d460d764ba3eff39a6d35d2d4

ac certify a86f388bdf..1330c88f66 (package root server/), profile immich
trees: 35c1ac1bea..720d5b8fa6
pathMap: 3 moves, 3 edited in place, 3458 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 3 moved files (5.3 s)
PASS  K1  Move-set integrity: 3 moves, 3 files edited in place, nothing added or deleted (2.2 s)
PASS  K2  Byte-span confinement: 4 specifier spans changed in 4 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 4 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.4 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.8 s)
PASS  K4  Location scan: 3 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (1 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) docs/docs/developer/architecture.mdx: line 64: 'src/controllers' is the directory server/src/controllers, whose contents change with the move of server/src/controllers/app.controller.spec.ts (moved to server/src/platform/bootstrap/app.controller.spec.ts)
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (50.0 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:97af69aa161618d42c2e43f7b4231cf86d13e27d460d764ba3eff39a6d35d2d4
041 R2 platform/check certified 1 file moved, 1 specifier edit in 1 file, 1 m 33 s

Commit dfcfd4323e8d4a2a70ca6a07d07c15678a45970b, tree f6e3e91be0ebc02d353fc519ed9c987b02236cc3

1 path moved
server/src/commands/schema-check.ts
  → server/src/platform/check/schema-check.ts

attempt 1: passed round 1, from b38343f4aa, 1 move, 1 m 33 s

Certificate: PASS (static checks) certificates/041-R2-platform-check.json

certificate JSON · digest sha256:9f7847f15185cb1a33c05b2a8029bfc9b1cafc29b8d576e5925ab60633eaa853

ac certify b38343f4aa..bc4c402d50 (package root server/), profile immich
trees: 720d5b8fa6..f6e3e91be0
pathMap: 1 moves, 1 edited in place, 3462 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 1 moved files (5.4 s)
PASS  K1  Move-set integrity: 1 moves, 1 files edited in place, nothing added or deleted (2.3 s)
PASS  K2  Byte-span confinement: 1 specifier spans changed in 1 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 1 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.8 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (7.0 s)
PASS  K4  Location scan: 1 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (0 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (50.3 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:9f7847f15185cb1a33c05b2a8029bfc9b1cafc29b8d576e5925ab60633eaa853
042 R2 platform/cron certified 1 file moved, 7 specifier edits in 7 files, 1 m 33 s

Commit c995602e0c3f9058834ce2500e20c4d8ccd8bd4a, tree f324141fa0dd4753fa52c308a4d60adc589c66e6

1 path moved
server/src/repositories/cron.repository.ts
  → server/src/platform/cron/cron.repository.ts

attempt 1: passed round 1, from dfcfd4323e, 1 move, 1 m 33 s

Certificate: PASS (static checks) certificates/042-R2-platform-cron.json

certificate JSON · digest sha256:2eceadab131c16949a1c45290704b0cc9b39a1853b82d1c9a2d123bff66cda3d

ac certify dfcfd4323e..e23fd88c7a (package root server/), profile immich
trees: f6e3e91be0..f324141fa0
pathMap: 1 moves, 7 edited in place, 3456 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 1 moved files (5.3 s)
PASS  K1  Move-set integrity: 1 moves, 7 files edited in place, nothing added or deleted (2.3 s)
PASS  K2  Byte-span confinement: 7 specifier spans changed in 7 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 7 rewritten specifiers keep their form (1.7 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.6 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (7.0 s)
PASS  K4  Location scan: 1 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (2 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/cron.repository.ts (moved to server/src/platform/cron/cron.repository.ts)
        finding (old-path-in-docs) docs/docs/developer/architecture.mdx: line 60: 'src/repositories' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/cron.repository.ts (moved to server/src/platform/cron/cron.repository.ts)
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (50.6 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:2eceadab131c16949a1c45290704b0cc9b39a1853b82d1c9a2d123bff66cda3d
043 R2 platform/crypto certified 1 file moved, 12 specifier edits in 12 files, 1 m 32 s

Commit 19338621e467b19b13d12338544abe1d0962f058, tree af9505307fb9340ea3737b03a98c2ba062edae72

1 path moved
server/src/repositories/crypto.repository.ts
  → server/src/platform/crypto/crypto.repository.ts

attempt 1: passed round 1, from c995602e0c, 1 move, 1 m 32 s

Certificate: PASS (static checks) certificates/043-R2-platform-crypto.json

certificate JSON · digest sha256:9278b63721c7b7a5d5ad1eb473559dfd00b642301d2e0e75081ec555d9a9bd3e

ac certify c995602e0c..a58ebfd956 (package root server/), profile immich
trees: f324141fa0..af9505307f
pathMap: 1 moves, 12 edited in place, 3451 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 1 moved files (5.3 s)
PASS  K1  Move-set integrity: 1 moves, 12 files edited in place, nothing added or deleted (2.4 s)
PASS  K2  Byte-span confinement: 12 specifier spans changed in 12 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 12 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.5 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.9 s)
PASS  K4  Location scan: 1 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (2 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/crypto.repository.ts (moved to server/src/platform/crypto/crypto.repository.ts)
        finding (old-path-in-docs) docs/docs/developer/architecture.mdx: line 60: 'src/repositories' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/crypto.repository.ts (moved to server/src/platform/crypto/crypto.repository.ts)
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (50.2 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:9278b63721c7b7a5d5ad1eb473559dfd00b642301d2e0e75081ec555d9a9bd3e
044 R2 platform/database certified 4 files moved, 104 specifier edits in 87 files, 1 m 33 s

Commit f9a730b698c693b92fabacfefd3ed7a40e7c814c, tree 4dc9f4d619fcf77c47b72fb4037f63bc9e70adf4

4 paths moved
server/src/database.ts
  → server/src/platform/database/database.ts
server/src/services/database.service.spec.ts
  → server/src/platform/database/database.service.spec.ts
server/src/services/database.service.ts
  → server/src/platform/database/database.service.ts
server/src/utils/database.ts
  → server/src/platform/database/utils/database.ts

attempt 1: passed round 1, from 19338621e4, 4 moves, 1 m 33 s

Certificate: PASS (static checks) certificates/044-R2-platform-database.json

certificate JSON · digest sha256:02b9e745714f356d676d1772a9ddd58bfb786aab86feed62d8038a7e39ae6e12

ac certify 19338621e4..7451d5899a (package root server/), profile immich
trees: af9505307f..4dc9f4d619
pathMap: 4 moves, 85 edited in place, 3375 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 4 moved files (5.2 s)
PASS  K1  Move-set integrity: 4 moves, 85 files edited in place, nothing added or deleted (2.4 s)
PASS  K2  Byte-span confinement: 104 specifier spans changed in 87 files; every other byte identical (0.8 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 104 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.8 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.9 s)
PASS  K4  Location scan: 4 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (6 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/database.service.spec.ts (moved to server/src/platform/database/database.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/database.service.spec.ts (moved to server/src/platform/database/database.service.spec.ts)
        … 4 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.3 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:02b9e745714f356d676d1772a9ddd58bfb786aab86feed62d8038a7e39ae6e12
045 R2 platform/event certified 2 files moved, 43 specifier edits in 42 files, 1 m 32 s

Commit e3ab6d217e8292784fed23d5f2fee09950e5fb5d, tree b2e65ff34f22f2a8f55613ada294cb7789482ae4

2 paths moved
server/src/repositories/event.repository.ts
  → server/src/platform/event/event.repository.ts
server/src/utils/event.ts
  → server/src/platform/event/event.ts

attempt 1: passed round 1, from f9a730b698, 2 moves, 1 m 32 s

Certificate: PASS (static checks) certificates/045-R2-platform-event.json

certificate JSON · digest sha256:bfe9c5cef8dbf3e25252954c0c0300ae33e955b0f8481ba39ec4931b7dce2f50

ac certify f9a730b698..6159bdf641 (package root server/), profile immich
trees: 4dc9f4d619..b2e65ff34f
pathMap: 2 moves, 41 edited in place, 3421 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 2 moved files (5.2 s)
PASS  K1  Move-set integrity: 2 moves, 41 files edited in place, nothing added or deleted (2.3 s)
PASS  K2  Byte-span confinement: 43 specifier spans changed in 42 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 43 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.4 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (7.1 s)
PASS  K4  Location scan: 2 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (3 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/event.repository.ts (moved to server/src/platform/event/event.repository.ts)
        finding (old-path-in-docs) docs/docs/developer/architecture.mdx: line 60: 'src/repositories' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/event.repository.ts (moved to server/src/platform/event/event.repository.ts)
        … 1 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.4 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:bfe9c5cef8dbf3e25252954c0c0300ae33e955b0f8481ba39ec4931b7dce2f50
046 R2 platform/file certified 2 files moved, 27 specifier edits in 25 files, 1 m 33 s

Commit 7350eb58eb18b0393a6449ba9433ed7cffcacfa7, tree f42c64a08c0d442d7c9785e8a2dfac9f29f147b5

2 paths moved
server/src/middleware/file-upload.interceptor.ts
  → server/src/platform/file/file-upload.interceptor.ts
server/src/utils/file.ts
  → server/src/platform/file/file.ts

attempt 1: passed round 1, from e3ab6d217e, 2 moves, 1 m 33 s

Certificate: PASS (static checks) certificates/046-R2-platform-file.json

certificate JSON · digest sha256:8107244c665070cb805b248dc1d9cd9d15d6c5285e6c7bbe6b847b358c25667d

ac certify e3ab6d217e..a71ccec443 (package root server/), profile immich
trees: b2e65ff34f..f42c64a08c
pathMap: 2 moves, 25 edited in place, 3437 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 2 moved files (5.3 s)
PASS  K1  Move-set integrity: 2 moves, 25 files edited in place, nothing added or deleted (2.4 s)
PASS  K2  Byte-span confinement: 27 specifier spans changed in 25 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 27 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.8 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (7.1 s)
PASS  K4  Location scan: 2 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (1 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (coverage-scope) server/test/vitest.config.mjs: line 19: 'src/utils/**' is the glob server/src/utils/** whose matches change (1 moved files, e.g. server/src/utils/file.ts -> server/src/platform/file/file.ts) of server/src/utils/file.ts (moved to server/src/platform/file/file.ts) [config at test.coverage.include]; coverage now measures a different file set (no coverage threshold in this file, so no gate changes)
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.4 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:8107244c665070cb805b248dc1d9cd9d15d6c5285e6c7bbe6b847b358c25667d
047 R2 platform/http-client certified 2 files moved, 2 specifier edits in 2 files, 1 m 32 s

Commit af075203b1b5aef732c55853ddc533414ae8df9a, tree 446f6e5158f77bb7f521059ff407c86fb70dfe8b

2 paths moved
server/src/utils/fetch.spec.ts
  → server/src/platform/http-client/fetch.spec.ts
server/src/utils/fetch.ts
  → server/src/platform/http-client/fetch.ts

attempt 1: passed round 1, from 7350eb58eb, 2 moves, 1 m 32 s

Certificate: PASS (static checks) certificates/047-R2-platform-http-client.json

certificate JSON · digest sha256:6892882b6e9c76908b395ced8662fd545dd2f6354772e3c3b45b892c1eee2b43

ac certify 7350eb58eb..c0bca1d148 (package root server/), profile immich
trees: f42c64a08c..446f6e5158
pathMap: 2 moves, 1 edited in place, 3461 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 2 moved files (5.3 s)
PASS  K1  Move-set integrity: 2 moves, 1 files edited in place, nothing added or deleted (2.4 s)
PASS  K2  Byte-span confinement: 2 specifier spans changed in 2 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 2 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.6 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.9 s)
PASS  K4  Location scan: 2 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (1 findings in docs, comments or ungated coverage settings) (5.6 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (coverage-scope) server/test/vitest.config.mjs: line 19: 'src/utils/**' is the glob server/src/utils/** whose matches change (2 moved files, e.g. server/src/utils/fetch.spec.ts -> server/src/platform/http-client/fetch.spec.ts) of server/src/utils/fetch.spec.ts (moved to server/src/platform/http-client/fetch.spec.ts) [config at test.coverage.include]; coverage now measures a different file set (no coverage threshold in this file, so no gate changes)
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.9 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:6892882b6e9c76908b395ced8662fd545dd2f6354772e3c3b45b892c1eee2b43
048 R2 platform/http-response certified 1 file moved, 8 specifier edits in 8 files, 1 m 31 s

Commit b8c64a980b0705e83570cf697ab334a5867dbb32, tree 97efb6fa2068825498b5620ee1880cd8f69fb19d

1 path moved
server/src/utils/response.ts
  → server/src/platform/http-response/response.ts

attempt 1: passed round 1, from af075203b1, 1 move, 1 m 31 s

Certificate: PASS (static checks) certificates/048-R2-platform-http-response.json

certificate JSON · digest sha256:20bf2ba2a0b89403de0b1be171234aa8d99af6daf4a8806268b9dd6999c9f97f

ac certify af075203b1..0d77b843ac (package root server/), profile immich
trees: 446f6e5158..97efb6fa20
pathMap: 1 moves, 8 edited in place, 3455 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 1 moved files (5.2 s)
PASS  K1  Move-set integrity: 1 moves, 8 files edited in place, nothing added or deleted (2.4 s)
PASS  K2  Byte-span confinement: 8 specifier spans changed in 8 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 8 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.6 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (7.0 s)
PASS  K4  Location scan: 1 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (1 findings in docs, comments or ungated coverage settings) (5.2 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (coverage-scope) server/test/vitest.config.mjs: line 19: 'src/utils/**' is the glob server/src/utils/** whose matches change (1 moved files, e.g. server/src/utils/response.ts -> server/src/platform/http-response/response.ts) of server/src/utils/response.ts (moved to server/src/platform/http-response/response.ts) [config at test.coverage.include]; coverage now measures a different file set (no coverage threshold in this file, so no gate changes)
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.8 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:20bf2ba2a0b89403de0b1be171234aa8d99af6daf4a8806268b9dd6999c9f97f
049 R2 platform/logging certified 6 files moved, 111 specifier edits in 104 files, 1 m 33 s

Commit 71c050c10843ac09bd0482151632ec3ec58dae6f, tree 327bd02c2511ea23007f5bb7c91df86bda64e834

6 paths moved
server/src/middleware/error.interceptor.ts
  → server/src/platform/logging/error.interceptor.ts
server/src/middleware/global-exception.filter.ts
  → server/src/platform/logging/global-exception.filter.ts
server/src/middleware/logging.interceptor.ts
  → server/src/platform/logging/logging.interceptor.ts
server/src/repositories/logging.repository.spec.ts
  → server/src/platform/logging/logging.repository.spec.ts
server/src/repositories/logging.repository.ts
  → server/src/platform/logging/logging.repository.ts
server/src/utils/logger.ts
  → server/src/platform/logging/logger.ts

attempt 1: passed round 1, from b8c64a980b, 6 moves, 1 m 33 s

Certificate: PASS (static checks) certificates/049-R2-platform-logging.json

certificate JSON · digest sha256:b3c0561f185b372e0b1bf96d7e1ea50ced1434d6aa75e99edf1bf4945c98109a

ac certify b8c64a980b..53b4294e9f (package root server/), profile immich
trees: 97efb6fa20..327bd02c25
pathMap: 6 moves, 99 edited in place, 3359 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 6 moved files (5.2 s)
PASS  K1  Move-set integrity: 6 moves, 99 files edited in place, nothing added or deleted (2.5 s)
PASS  K2  Byte-span confinement: 111 specifier spans changed in 104 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 111 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.3 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (7.1 s)
PASS  K4  Location scan: 6 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (3 findings in docs, comments or ungated coverage settings) (5.4 s)
        finding (stack-text) server/src/utils/logger.ts: moved to server/src/platform/logging/logger.ts; 1 stack-trace reads passed along as text (line 24); their frames now name the new path
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/logging.repository.spec.ts (moved to server/src/platform/logging/logging.repository.spec.ts)
        … 2 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.3 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:b3c0561f185b372e0b1bf96d7e1ea50ced1434d6aa75e99edf1bf4945c98109a
050 R2 platform/media certified 8 files moved, 15 specifier edits in 14 files, 1 m 33 s

Commit 99c3a69250885bea8261d28b592c9a65570b30a2, tree 8a261d152b199b40267e4c8d10844bc5ff52e6cf

8 paths moved
server/src/commands/media-location.command.ts
  → server/src/platform/media/media-location.command.ts
server/src/repositories/media.repository.spec.ts
  → server/src/platform/media/media.repository.spec.ts
server/src/repositories/media.repository.ts
  → server/src/platform/media/media.repository.ts
server/src/services/media.service.spec.ts
  → server/src/platform/media/media.service.spec.ts
server/src/services/media.service.ts
  → server/src/platform/media/media.service.ts
server/src/utils/editor.spec.ts
  → server/src/platform/media/editor.spec.ts
server/src/utils/editor.ts
  → server/src/platform/media/editor.ts
server/src/utils/media.ts
  → server/src/platform/media/media.ts

attempt 1: passed round 1, from 71c050c108, 8 moves, 1 m 33 s

Certificate: PASS (static checks) certificates/050-R2-platform-media.json

certificate JSON · digest sha256:79c8b8b7a9a047664899b713f690cd88dc509522ef97f250e597ebdfb2fc3ed8

ac certify 71c050c108..51667efd5c (package root server/), profile immich
trees: 327bd02c25..8a261d152b
pathMap: 8 moves, 10 edited in place, 3446 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 8 moved files (5.3 s)
PASS  K1  Move-set integrity: 8 moves, 10 files edited in place, nothing added or deleted (2.6 s)
PASS  K2  Byte-span confinement: 15 specifier spans changed in 14 files; every other byte identical (0.8 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 15 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.6 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (7.2 s)
PASS  K4  Location scan: 8 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/media.service.spec.ts (moved to server/src/platform/media/media.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/media.repository.spec.ts (moved to server/src/platform/media/media.repository.spec.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.1 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:79c8b8b7a9a047664899b713f690cd88dc509522ef97f250e597ebdfb2fc3ed8
051 R2 platform/metadata certified 4 files moved, 15 specifier edits in 11 files, 1 m 31 s

Commit 700c178708037183b9f342888b31b1c97e487428, tree ec245a9ea7f2c3096583b407b2aee494d144ac5c

4 paths moved
server/src/repositories/metadata.repository.ts
  → server/src/platform/metadata/metadata.repository.ts
server/src/services/metadata.service.spec.ts
  → server/src/platform/metadata/metadata.service.spec.ts
server/src/services/metadata.service.ts
  → server/src/platform/metadata/metadata.service.ts
server/src/utils/tasks.ts
  → server/src/platform/metadata/tasks.ts

attempt 1: passed round 1, from 99c3a69250, 4 moves, 1 m 31 s

Certificate: PASS (static checks) certificates/051-R2-platform-metadata.json

certificate JSON · digest sha256:1dc3abdb72a1924860f7647d8bf2eea10afc5097959686d083f2766d14f5c2a4

ac certify 99c3a69250..c8f5f03748 (package root server/), profile immich
trees: 8a261d152b..ec245a9ea7
pathMap: 4 moves, 9 edited in place, 3451 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 4 moved files (5.2 s)
PASS  K1  Move-set integrity: 4 moves, 9 files edited in place, nothing added or deleted (2.3 s)
PASS  K2  Byte-span confinement: 15 specifier spans changed in 11 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 15 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.5 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.8 s)
PASS  K4  Location scan: 4 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.6 s)
        finding (stack-text) server/src/repositories/metadata.repository.ts: moved to server/src/platform/metadata/metadata.repository.ts; 1 stack-trace reads passed along as text (line 133); their frames now name the new path
        finding (stack-text) server/src/services/metadata.service.ts: moved to server/src/platform/metadata/metadata.service.ts; 2 stack-trace reads passed along as text (line 170); their frames now name the new path
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        … 8 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.6 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.6 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:1dc3abdb72a1924860f7647d8bf2eea10afc5097959686d083f2766d14f5c2a4
052 R2 platform/move certified 1 file moved, 4 specifier edits in 4 files, 1 m 31 s

Commit 71acdb6e2896302b182dcebe4d8ac130afd414c0, tree 869cebd5ac23133a99b8d5c0ca728a8761e3544d

1 path moved
server/src/repositories/move.repository.ts
  → server/src/platform/move/move.repository.ts

attempt 1: passed round 1, from 700c178708, 1 move, 1 m 31 s

Certificate: PASS (static checks) certificates/052-R2-platform-move.json

certificate JSON · digest sha256:f53cddd6e471c308ca3524aa9d0020795bad5a80f2f3d0d76734e4fbfb17a9f7

ac certify 700c178708..a8abda6f0f (package root server/), profile immich
trees: ec245a9ea7..869cebd5ac
pathMap: 1 moves, 4 edited in place, 3459 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 1 moved files (5.2 s)
PASS  K1  Move-set integrity: 1 moves, 4 files edited in place, nothing added or deleted (2.3 s)
PASS  K2  Byte-span confinement: 4 specifier spans changed in 4 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 4 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.6 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.7 s)
PASS  K4  Location scan: 1 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (2 findings in docs, comments or ungated coverage settings) (5.4 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/move.repository.ts (moved to server/src/platform/move/move.repository.ts)
        finding (old-path-in-docs) docs/docs/developer/architecture.mdx: line 60: 'src/repositories' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/move.repository.ts (moved to server/src/platform/move/move.repository.ts)
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.4 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:f53cddd6e471c308ca3524aa9d0020795bad5a80f2f3d0d76734e4fbfb17a9f7
053 R2 platform/process certified 2 files moved, 7 specifier edits in 7 files, 1 m 31 s

Commit 54998b5d84b1798ab8ebc370675dab9615c03d34, tree 5d6acf1db837569f70d8164753b8ae3b455933e6

2 paths moved
server/src/repositories/process.repository.spec.ts
  → server/src/platform/process/process.repository.spec.ts
server/src/repositories/process.repository.ts
  → server/src/platform/process/process.repository.ts

attempt 1: passed round 1, from 71acdb6e28, 2 moves, 1 m 31 s

Certificate: PASS (static checks) certificates/053-R2-platform-process.json

certificate JSON · digest sha256:7996d66314421817b6e2f69a5d8a44025ad1aca863f42415eb9dff2ec548a06a

ac certify 71acdb6e28..804aef06fe (package root server/), profile immich
trees: 869cebd5ac..5d6acf1db8
pathMap: 2 moves, 6 edited in place, 3456 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 2 moved files (5.3 s)
PASS  K1  Move-set integrity: 2 moves, 6 files edited in place, nothing added or deleted (2.2 s)
PASS  K2  Byte-span confinement: 7 specifier spans changed in 7 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 7 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.4 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (7.1 s)
PASS  K4  Location scan: 2 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (2 findings in docs, comments or ungated coverage settings) (5.6 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/process.repository.spec.ts (moved to server/src/platform/process/process.repository.spec.ts)
        finding (old-path-in-docs) docs/docs/developer/architecture.mdx: line 60: 'src/repositories' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/process.repository.spec.ts (moved to server/src/platform/process/process.repository.spec.ts)
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.0 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:7996d66314421817b6e2f69a5d8a44025ad1aca863f42415eb9dff2ec548a06a
054 R2 platform/registry certified 7 files moved, 74 specifier edits in 71 files, 1 m 33 s

Commit be7267223af13e07f3e6819652ed8f1c45a6501a, tree dd149b5cdd6370749ccc2efd668c8a758c4fe4f9

7 paths moved
server/src/app.module.ts
  → server/src/platform/registry/app.module.ts
server/src/commands/index.ts
  → server/src/platform/registry/commands/index.ts
server/src/controllers/index.spec.ts
  → server/src/platform/registry/controllers/index.spec.ts
server/src/controllers/index.ts
  → server/src/platform/registry/controllers/index.ts
server/src/repositories/index.ts
  → server/src/platform/registry/repositories/index.ts
server/src/services/base.service.ts
  → server/src/platform/registry/base.service.ts
server/src/services/index.ts
  → server/src/platform/registry/services/index.ts

attempt 1: passed round 1, from 54998b5d84, 7 moves, 1 m 33 s

Certificate: PASS (static checks) certificates/054-R2-platform-registry.json

certificate JSON · digest sha256:821b5e167a89d81d2e0b9e9aaac4b8aef45aef55388d9ac2f8864c07da076791

ac certify 54998b5d84..07006eb4d4 (package root server/), profile immich
trees: 5d6acf1db8..dd149b5cdd
pathMap: 7 moves, 69 edited in place, 3388 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 7 moved files (5.2 s)
PASS  K1  Move-set integrity: 7 moves, 69 files edited in place, nothing added or deleted (2.2 s)
PASS  K2  Byte-span confinement: 74 specifier spans changed in 71 files; every other byte identical (0.8 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 74 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.2 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.8 s)
PASS  K4  Location scan: 7 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the old directory of an index file of server/src/services/index.ts (moved to server/src/platform/registry/services/index.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the old directory of an index file of server/src/repositories/index.ts (moved to server/src/platform/registry/repositories/index.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.5 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:821b5e167a89d81d2e0b9e9aaac4b8aef45aef55388d9ac2f8864c07da076791
055 R2 platform/storage certified 7 files moved, 55 specifier edits in 45 files, 1 m 33 s

Commit 75a721923d76e3adc220e0bfb155915a8df653d9, tree 66a0cb2b9f928990a4fc6bd09078c883292c08b4

7 paths moved
server/src/cores/storage.core.spec.ts
  → server/src/platform/storage/storage.core.spec.ts
server/src/cores/storage.core.ts
  → server/src/platform/storage/storage.core.ts
server/src/repositories/storage.repository.ts
  → server/src/platform/storage/storage.repository.ts
server/src/services/storage-template.service.spec.ts
  → server/src/platform/storage/storage-template.service.spec.ts
server/src/services/storage-template.service.ts
  → server/src/platform/storage/storage-template.service.ts
server/src/services/storage.service.spec.ts
  → server/src/platform/storage/storage.service.spec.ts
server/src/services/storage.service.ts
  → server/src/platform/storage/storage.service.ts

attempt 1: passed round 1, from be7267223a, 7 moves, 1 m 33 s

Certificate: PASS (static checks) certificates/055-R2-platform-storage.json

certificate JSON · digest sha256:5b7d8e3365b3d26dbe3ff59354a5d8f0873bb5685e9edc48227c8d976b09798d

ac certify be7267223a..3fe302817b (package root server/), profile immich
trees: dd149b5cdd..66a0cb2b9f
pathMap: 7 moves, 39 edited in place, 3418 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 7 moved files (5.3 s)
PASS  K1  Move-set integrity: 7 moves, 39 files edited in place, nothing added or deleted (2.3 s)
PASS  K2  Byte-span confinement: 55 specifier spans changed in 45 files; every other byte identical (0.8 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 55 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.1 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.8 s)
PASS  K4  Location scan: 7 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (stack-text) server/src/services/storage-template.service.ts: moved to server/src/platform/storage/storage-template.service.ts; 1 stack-trace reads passed along as text (line 263); their frames now name the new path
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/storage-template.service.spec.ts (moved to server/src/platform/storage/storage-template.service.spec.ts)
        … 7 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.7 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:5b7d8e3365b3d26dbe3ff59354a5d8f0873bb5685e9edc48227c8d976b09798d
056 R2 platform/telemetry certified 2 files moved, 10 specifier edits in 10 files, 1 m 31 s

Commit 945d1b921c8d0c39043ca3507f450770306e951f, tree b1bca129f697bac27ef2c647fd817d8eeeeb44f9

2 paths moved
server/src/repositories/telemetry.repository.ts
  → server/src/platform/telemetry/telemetry.repository.ts
server/src/services/telemetry.service.ts
  → server/src/platform/telemetry/telemetry.service.ts

attempt 1: passed round 1, from 75a721923d, 2 moves, 1 m 31 s

Certificate: PASS (static checks) certificates/056-R2-platform-telemetry.json

certificate JSON · digest sha256:514d1bd551c8f61bfd70886c8d8dae512fbc83fb794812a740a4d4011ae18986

ac certify 75a721923d..c441a7c117 (package root server/), profile immich
trees: 66a0cb2b9f..b1bca129f6
pathMap: 2 moves, 10 edited in place, 3452 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 2 moved files (5.3 s)
PASS  K1  Move-set integrity: 2 moves, 10 files edited in place, nothing added or deleted (2.2 s)
PASS  K2  Byte-span confinement: 10 specifier spans changed in 10 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 10 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (7.8 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.9 s)
PASS  K4  Location scan: 2 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (6 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/telemetry.service.ts (moved to server/src/platform/telemetry/telemetry.service.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/telemetry.repository.ts (moved to server/src/platform/telemetry/telemetry.repository.ts)
        … 4 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.5 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:514d1bd551c8f61bfd70886c8d8dae512fbc83fb794812a740a4d4011ae18986
057 R2 platform/transcoding certified 2 files moved, 2 specifier edits in 2 files, 1 m 31 s

Commit 342dac06cad209c23e0b4e1f44771cb96bc92767, tree c2606fadaca621b66da6f7fada8150ae9da6d713

2 paths moved
server/src/services/transcoding.service.spec.ts
  → server/src/platform/transcoding/transcoding.service.spec.ts
server/src/services/transcoding.service.ts
  → server/src/platform/transcoding/transcoding.service.ts

attempt 1: passed round 1, from 945d1b921c, 2 moves, 1 m 31 s

Certificate: PASS (static checks) certificates/057-R2-platform-transcoding.json

certificate JSON · digest sha256:f64c793d74e44efa4040c50679a58de65bdb91787f2782a3648b8affaacfd4c3

ac certify 945d1b921c..9d670a6abd (package root server/), profile immich
trees: b1bca129f6..c2606fadac
pathMap: 2 moves, 1 edited in place, 3461 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 2 moved files (5.4 s)
PASS  K1  Move-set integrity: 2 moves, 1 files edited in place, nothing added or deleted (2.3 s)
PASS  K2  Byte-span confinement: 2 specifier spans changed in 2 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 2 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.3 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.8 s)
PASS  K4  Location scan: 2 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (5 findings in docs, comments or ungated coverage settings) (5.2 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/transcoding.service.spec.ts (moved to server/src/platform/transcoding/transcoding.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/transcoding.service.spec.ts (moved to server/src/platform/transcoding/transcoding.service.spec.ts)
        … 3 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.7 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:f64c793d74e44efa4040c50679a58de65bdb91787f2782a3648b8affaacfd4c3
058 R2 platform/websocket certified 2 files moved, 8 specifier edits in 8 files, 1 m 32 s

Commit 9710213d6994fdc4939f6d27e6969e40b0affd62, tree 29a75536ca9cc63bc1b7613587cf175e79da01cb

2 paths moved
server/src/middleware/websocket.adapter.ts
  → server/src/platform/websocket/websocket.adapter.ts
server/src/repositories/websocket.repository.ts
  → server/src/platform/websocket/websocket.repository.ts

attempt 1: passed round 1, from 342dac06ca, 2 moves, 1 m 32 s

Certificate: PASS (static checks) certificates/058-R2-platform-websocket.json

certificate JSON · digest sha256:c4193cd30f687e7981f3b49eb6b9856666f5f34fccaf7930e63cd75a786b9953

ac certify 342dac06ca..b4cccaeb98 (package root server/), profile immich
trees: c2606fadac..29a75536ca
pathMap: 2 moves, 8 edited in place, 3454 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 2 moved files (5.3 s)
PASS  K1  Move-set integrity: 2 moves, 8 files edited in place, nothing added or deleted (2.3 s)
PASS  K2  Byte-span confinement: 8 specifier spans changed in 8 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 8 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.2 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (7.0 s)
PASS  K4  Location scan: 2 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (2 findings in docs, comments or ungated coverage settings) (5.2 s)
        finding (stack-text) server/src/repositories/websocket.repository.ts: moved to server/src/platform/websocket/websocket.repository.ts; 1 stack-trace reads passed along as text (line 95); their frames now name the new path
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/websocket.repository.ts (moved to server/src/platform/websocket/websocket.repository.ts)
        … 1 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.7 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:c4193cd30f687e7981f3b49eb6b9856666f5f34fccaf7930e63cd75a786b9953
059 R2 shared/shared certified 20 files moved, 700 specifier edits in 411 files, 1 m 36 s

Commit 775d52db5e82037e73aa66cde6f8a0fd3fdc720d, tree 7dfa3b6c72a2f7b096f6d7b6821b51bc3df1c8db

20 paths moved
server/src/decorators.ts
  → server/src/shared/decorators.ts
server/src/dtos/env.dto.ts
  → server/src/shared/env.dto.ts
server/src/enum.ts
  → server/src/shared/enum.ts
server/src/services/api.service.spec.ts
  → server/src/shared/api.service.spec.ts
server/src/services/api.service.ts
  → server/src/shared/api.service.ts
server/src/types.ts
  → server/src/shared/types.ts
server/src/utils/bytes.ts
  → server/src/shared/bytes.ts
server/src/utils/date.spec.ts
  → server/src/shared/date.spec.ts
server/src/utils/date.ts
  → server/src/shared/date.ts
server/src/utils/mime-types.spec.ts
  → server/src/shared/mime-types.spec.ts
server/src/utils/mime-types.ts
  → server/src/shared/mime-types.ts
server/src/utils/object.ts
  → server/src/shared/object.ts
server/src/utils/pagination.ts
  → server/src/shared/pagination.ts
server/src/utils/preferences.ts
  → server/src/shared/preferences.ts
server/src/utils/request.spec.ts
  → server/src/shared/request.spec.ts
server/src/utils/request.ts
  → server/src/shared/request.ts
server/src/utils/transform.spec.ts
  → server/src/shared/transform.spec.ts
server/src/utils/transform.ts
  → server/src/shared/transform.ts
server/src/validation.spec.ts
  → server/src/shared/validation.spec.ts
server/src/validation.ts
  → server/src/shared/validation.ts

attempt 1: passed round 1, from 9710213d69, 20 moves, 1 m 36 s

Certificate: PASS (static checks) certificates/059-R2-shared-shared.json

certificate JSON · digest sha256:c974d003c3af07901cdf4a6c709e50e50915a5fcb7db005f2d443b72f3e64b23

ac certify 9710213d69..ec4c596d97 (package root server/), profile immich
trees: 29a75536ca..7dfa3b6c72
pathMap: 20 moves, 398 edited in place, 3046 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 20 moved files (5.3 s)
PASS  K1  Move-set integrity: 20 moves, 398 files edited in place, nothing added or deleted (2.2 s)
PASS  K2  Byte-span confinement: 700 specifier spans changed in 411 files; every other byte identical (0.9 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 700 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (5.8 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.9 s)
PASS  K4  Location scan: 20 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
        finding (old-path-in-docs) .github/pull_request_template.md: line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/api.service.spec.ts (moved to server/src/shared/api.service.spec.ts)
        finding (old-path-in-docs) .github/pull_request_template.md: line 37: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/api.service.spec.ts (moved to server/src/shared/api.service.spec.ts)
        … 6 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (49.8 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:c974d003c3af07901cdf4a6c709e50e50915a5fcb7db005f2d443b72f3e64b23
060 R3 module/search certified 2 files moved, 2 specifier edits in 2 files, 1 m 30 s

Commit 8eac5f6107f02e256de5e5f61ea0a6990d9fb3aa, tree c94d47662aa08f066a91f7687203ee7faee7180b

2 paths moved
server/src/modules/search/search-filter.spec.ts
  → server/src/modules/search/search.filter.spec.ts
server/src/modules/search/search-filter.ts
  → server/src/modules/search/search.filter.ts

attempt 1: passed round 1, from 775d52db5e, 2 moves, 1 m 30 s

Certificate: PASS (static checks) certificates/060-R3-module-search.json

certificate JSON · digest sha256:b775e6f44ed8b4f02be65da19e6177d582b3ed03e83d94f20a1d9960855baf70

ac certify 775d52db5e..b9a7001f2a (package root server/), profile immich
trees: 7dfa3b6c72..c94d47662a
pathMap: 2 moves, 1 edited in place, 3461 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 2 moved files (5.2 s)
PASS  K1  Move-set integrity: 2 moves, 1 files edited in place, nothing added or deleted (2.1 s)
PASS  K2  Byte-span confinement: 2 specifier spans changed in 2 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 2 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.4 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (7.0 s)
PASS  K4  Location scan: 2 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (0 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.7 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:b775e6f44ed8b4f02be65da19e6177d582b3ed03e83d94f20a1d9960855baf70
061 R3 module/view certified 1 file moved, 3 specifier edits in 3 files, 1 m 31 s

Commit f4965adc1f68b660bbec45ef0b8ad158b72e742a, tree 199d3a6f41a5b0db356f4413556dfd11073c2772

1 path moved
server/src/modules/view/view-repository.ts
  → server/src/modules/view/view.repository.ts

attempt 1: passed round 1, from 8eac5f6107, 1 move, 1 m 31 s

Certificate: PASS (static checks) certificates/061-R3-module-view.json

certificate JSON · digest sha256:70dc3f40d8186e75c0ba7cace201511584e1ca0ddf8144fb2324c9acdb1b8a21

ac certify 8eac5f6107..ceed7e5ae9 (package root server/), profile immich
trees: c94d47662a..199d3a6f41
pathMap: 1 moves, 3 edited in place, 3460 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 1 moved files (5.2 s)
PASS  K1  Move-set integrity: 1 moves, 3 files edited in place, nothing added or deleted (2.2 s)
PASS  K2  Byte-span confinement: 3 specifier spans changed in 3 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 3 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.4 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.9 s)
PASS  K4  Location scan: 1 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (0 findings in docs, comments or ungated coverage settings) (5.2 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.9 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:70dc3f40d8186e75c0ba7cace201511584e1ca0ddf8144fb2324c9acdb1b8a21
062 R3 shared/shared certified 2 files moved, 13 specifier edits in 13 files, 1 m 30 s

Commit 91a57545b7898352df944e09cc0f38eaadbbd89d, tree 6a8a901cbb01c97f5d421020421828f493922ba5

2 paths moved
server/src/shared/mime-types.spec.ts
  → server/src/shared/mime.types.spec.ts
server/src/shared/mime-types.ts
  → server/src/shared/mime.types.ts

attempt 1: passed round 1, from f4965adc1f, 2 moves, 1 m 30 s

Certificate: PASS (static checks) certificates/062-R3-shared-shared.json

certificate JSON · digest sha256:9457bec5a0d699c7c5341423fd48b0afae406c6fb32ee2c95848630283dc34af

ac certify f4965adc1f..d9311758a7 (package root server/), profile immich
trees: 199d3a6f41..6a8a901cbb
pathMap: 2 moves, 12 edited in place, 3450 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 2 moved files (5.2 s)
PASS  K1  Move-set integrity: 2 moves, 12 files edited in place, nothing added or deleted (2.3 s)
PASS  K2  Byte-span confinement: 13 specifier spans changed in 13 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 13 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.2 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (7.0 s)
PASS  K4  Location scan: 2 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (0 findings in docs, comments or ungated coverage settings) (5.0 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.8 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e

verdict: PASS (static checks only)
digest: sha256:9457bec5a0d699c7c5341423fd48b0afae406c6fb32ee2c95848630283dc34af
063 R4 boundaries certified boundary rules added, 4 m 40 s

Commit c4be040b5739351507750669c3a179dd752f4a72, tree 4e457bb4e806f1bc0a63b83141345e20edab0f57

attempt 1: passed round 1, from 91a57545b7, 0 moves, 4 m 40 s

80 rules over 38 modules (8 back-edges against the DAG order), 161 known violations frozen in the baseline, 80/80 rules fired on their synthetic violation; check from server/ with `npx -y -p dependency-cruiser@18.6.0 -p typescript@6.0.2 depcruise src --config .dependency-cruiser.json --ignore-known .dependency-cruiser-known-violations.json`

Certificate: PASS (static checks and oracles) rungs/R4.json

certificate JSON · digest sha256:c57590c655d8e83e44aea69fd39c09d701371379e702c6accd4c097bb2f7c0ec

ac certify 91a57545b7..b609f38a4a (package root server/), profile immich
trees: 6a8a901cbb..4e457bb4e8
pathMap: 0 moves, 0 edited in place, 3464 unchanged, 2 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 0 moved files (5.3 s)
PASS  K1  Move-set integrity: 0 moves, 0 files edited in place, 2 inert tool configs added, nothing else added or deleted (8.2 s)
        finding (tool-config-added) server/.dependency-cruiser-known-violations.json: added at the package root and proven inert: in no tsconfig program, loaded by no reference, packed by no published package, named or globbed by no other file, and the tool runs nowhere; CI path filters match it, so it triggers their jobs: 'server/**' in .github/workflows/docker.yml (line 45), 'server/**' in .github/workflows/test.yml (line 46)
        finding (tool-config-added) server/.dependency-cruiser.json: added at the package root and proven inert: in no tsconfig program, loaded by no reference, packed by no published package, named or globbed by no other file, and the tool runs nowhere; CI path filters match it, so it triggers their jobs: 'server/**' in .github/workflows/docker.yml (line 45), 'server/**' in .github/workflows/test.yml (line 46)
PASS  K2  Byte-span confinement: 0 specifier spans changed in 0 files; every other byte identical (0.0 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 0 rewritten specifiers keep their form (1.9 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (6.7 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.8 s)
PASS  K4  Location scan: 0 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (0 findings in docs, comments or ungated coverage settings) (0.3 s)
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.6 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.7 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e
PASS  K8  Oracles on the commit: tsc exit 0; unit 105/105 files and 2,337/2,337 cases equal to base (head: 105/105 files load, 2,337 passed, 0 failed, 0 skipped); openapi byte-identical to the base's open-api/immich-openapi-specs.json (947,932 bytes) (170.7 s)

verdict: PASS (static checks and oracles)
digest: sha256:c57590c655d8e83e44aea69fd39c09d701371379e702c6accd4c097bb2f7c0ec
Time per step
certify (static checks)move and commitfault, amend, rollback
0100 s200 s300 s16111621263136R141465156R261R3R463

Seconds per step, from run.json attempt timings. R4 has no static step certificate: its time is its rung certificate (with oracles).

Table view
#RungGroupMove + commit (s)Certify (s)Other (s)Failed attempts (s)
1R1module/activity8.6132.60.10.0
2R1module/album8.979.40.10.0
3R1module/api-key8.779.10.10.0
4R1module/asset10.380.60.10.0
5R1module/auth10.380.10.10.0
6R1module/cluster-group8.781.20.10.0
7R1module/config9.480.60.10.0
8R1module/database-backup8.880.10.10.0
9R1module/download8.779.40.10.0
10R1module/duplicate9.080.00.10.0
11R1module/integrity9.080.00.10.0
12R1module/job8.979.80.10.0
13R1module/library9.179.90.10.0
14R1module/machine-learning8.879.90.10.0
15R1module/maintenance9.579.30.10.0
16R1module/map9.079.20.10.0
17R1module/memory8.978.60.10.0
18R1module/notification9.478.70.10.0
19R1module/ocr8.980.10.10.0
20R1module/partner9.078.70.10.0
21R1module/person9.478.80.10.0
22R1module/plugin9.179.80.10.0
23R1module/queue9.079.20.10.0
24R1module/search9.781.70.10.0
25R1module/server9.280.80.10.0
26R1module/session9.179.20.10.0
27R1module/shared-link9.481.20.10.0
28R1module/stack9.481.30.10.0
29R1module/sync9.481.40.10.0
30R1module/system-metadata9.781.30.10.0
31R1module/tag9.681.20.10.0
32R1module/timeline9.179.90.10.0
33R1module/trash9.280.10.10.0
34R1module/user10.384.00.10.0
35R1module/version9.383.50.10.0
36R1module/video-stream9.382.00.10.0
37R1module/view9.382.30.10.0
38R1module/workflow9.381.00.10.0
39R2platform/access9.783.20.10.0
40R2platform/bootstrap9.182.50.10.0
41R2platform/check8.983.60.10.0
42R2platform/cron9.083.50.10.0
43R2platform/crypto9.183.10.10.0
44R2platform/database10.282.20.10.0
45R2platform/event9.682.50.10.0
46R2platform/file9.583.00.10.0
47R2platform/http-client9.083.20.10.0
48R2platform/http-response9.081.80.10.0
49R2platform/logging10.283.00.10.0
50R2platform/media9.782.90.10.0
51R2platform/metadata9.381.60.10.0
52R2platform/move9.182.00.10.0
53R2platform/process9.282.10.10.0
54R2platform/registry10.782.30.10.0
55R2platform/storage10.182.40.10.0
56R2platform/telemetry9.581.60.10.0
57R2platform/transcoding9.281.20.10.0
58R2platform/websocket9.482.20.10.0
59R2shared/shared13.182.30.10.0
60R3module/search8.981.20.10.0
61R3module/view9.281.30.10.0
62R3shared/shared9.381.10.10.0
63R4boundaries0.1256.40.00.0

Rung certificates

R1 rung certificate: PASS (static checks and oracles) rungs/R1.json

certificate JSON · digest sha256:d03d02e7de2c1d09739f0703ba22000075fd3ead7488369cfd87708f2b37984b

ac certify 02063972e8..2f35e608a3 (package root server/), profile immich
trees: 424df72c34..eae80d417f
pathMap: 286 moves, 130 edited in place, 3048 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 286 moved files (0.2 s)
PASS  K1  Move-set integrity: 286 moves, 130 files edited in place, nothing added or deleted (2.0 s)
PASS  K2  Byte-span confinement: 1227 specifier spans changed in 352 files; every other byte identical (3.0 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 1227 rewritten specifiers keep their form (1.6 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (6.3 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.7 s)
PASS  K4  Location scan: 286 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (9 findings in docs, comments or ungated coverage settings) (5.7 s)
        finding (stack-text) server/src/services/asset-media.service.ts: moved to server/src/modules/asset/asset-media.service.ts; 1 stack-trace reads passed along as text (line 224); their frames now name the new path
        finding (stack-text) server/src/services/auth.service.ts: moved to server/src/modules/auth/auth.service.ts; 1 stack-trace reads passed along as text (line 403); their frames now name the new path
        finding (stack-text) server/src/services/duplicate.service.ts: moved to server/src/modules/duplicate/duplicate.service.ts; 1 stack-trace reads passed along as text (line 104); their frames now name the new path
        … 14 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (0.0 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e
PASS  K8  Oracles on the commit: tsc exit 0; unit 105/105 files and 2,337/2,337 cases equal to base (head: 105/105 files load, 2,337 passed, 0 failed, 0 skipped); openapi byte-identical to the base's open-api/immich-openapi-specs.json (947,932 bytes) (116.1 s)

verdict: PASS (static checks and oracles)
digest: sha256:d03d02e7de2c1d09739f0703ba22000075fd3ead7488369cfd87708f2b37984b
R2 rung certificate: PASS (static checks and oracles) rungs/R2.json

certificate JSON · digest sha256:0d0cf9a3bae58090bbe1a9f7bd41cfe5dd71fab780a557c85607e33183108703

ac certify 2f35e608a3..775d52db5e (package root server/), profile immich
trees: eae80d417f..7dfa3b6c72
pathMap: 81 moves, 403 edited in place, 2980 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 81 moved files (0.2 s)
PASS  K1  Move-set integrity: 81 moves, 403 files edited in place, nothing added or deleted (2.3 s)
PASS  K2  Byte-span confinement: 1247 specifier spans changed in 469 files; every other byte identical (1.3 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 1247 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (6.0 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (7.1 s)
PASS  K4  Location scan: 81 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (13 findings in docs, comments or ungated coverage settings) (5.3 s)
        finding (stack-text) server/src/repositories/metadata.repository.ts: moved to server/src/platform/metadata/metadata.repository.ts; 1 stack-trace reads passed along as text (line 133); their frames now name the new path
        finding (stack-text) server/src/repositories/websocket.repository.ts: moved to server/src/platform/websocket/websocket.repository.ts; 1 stack-trace reads passed along as text (line 95); their frames now name the new path
        finding (stack-text) server/src/services/metadata.service.ts: moved to server/src/platform/metadata/metadata.service.ts; 2 stack-trace reads passed along as text (line 170); their frames now name the new path
        … 16 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (0.0 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e
PASS  K8  Oracles on the commit: tsc exit 0; unit 105/105 files and 2,337/2,337 cases equal to base (head: 105/105 files load, 2,337 passed, 0 failed, 0 skipped); openapi byte-identical to the base's open-api/immich-openapi-specs.json (947,932 bytes) (170.7 s)

verdict: PASS (static checks and oracles)
digest: sha256:0d0cf9a3bae58090bbe1a9f7bd41cfe5dd71fab780a557c85607e33183108703
R3 rung certificate: PASS (static checks and oracles) rungs/R3.json

certificate JSON · digest sha256:043030173380b8fd7aaae467c0a67bcc72ed19d66f9d8eb89933e809a849350d

ac certify 775d52db5e..91a57545b7 (package root server/), profile immich
trees: 7dfa3b6c72..6a8a901cbb
pathMap: 5 moves, 16 edited in place, 3443 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 5 moved files (0.4 s)
PASS  K1  Move-set integrity: 5 moves, 16 files edited in place, nothing added or deleted (2.4 s)
PASS  K2  Byte-span confinement: 18 specifier spans changed in 18 files; every other byte identical (0.7 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 18 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (8.1 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (7.1 s)
PASS  K4  Location scan: 5 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (0 findings in docs, comments or ungated coverage settings) (5.6 s)
        finding (opaque-dynamic-load) server/src/repositories/database.repository.ts: line 510: import(filePath) loads a module by a path K4 can't evaluate
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (0.0 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e
PASS  K8  Oracles on the commit: tsc exit 0; unit 105/105 files and 2,337/2,337 cases equal to base (head: 105/105 files load, 2,337 passed, 0 failed, 0 skipped); openapi byte-identical to the base's open-api/immich-openapi-specs.json (947,932 bytes) (169.5 s)

verdict: PASS (static checks and oracles)
digest: sha256:043030173380b8fd7aaae467c0a67bcc72ed19d66f9d8eb89933e809a849350d
R4 rung certificate: PASS (static checks and oracles) rungs/R4.json

certificate JSON · digest sha256:c57590c655d8e83e44aea69fd39c09d701371379e702c6accd4c097bb2f7c0ec

ac certify 91a57545b7..b609f38a4a (package root server/), profile immich
trees: 6a8a901cbb..4e457bb4e8
pathMap: 0 moves, 0 edited in place, 3464 unchanged, 2 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 0 moved files (5.3 s)
PASS  K1  Move-set integrity: 0 moves, 0 files edited in place, 2 inert tool configs added, nothing else added or deleted (8.2 s)
        finding (tool-config-added) server/.dependency-cruiser-known-violations.json: added at the package root and proven inert: in no tsconfig program, loaded by no reference, packed by no published package, named or globbed by no other file, and the tool runs nowhere; CI path filters match it, so it triggers their jobs: 'server/**' in .github/workflows/docker.yml (line 45), 'server/**' in .github/workflows/test.yml (line 46)
        finding (tool-config-added) server/.dependency-cruiser.json: added at the package root and proven inert: in no tsconfig program, loaded by no reference, packed by no published package, named or globbed by no other file, and the tool runs nowhere; CI path filters match it, so it triggers their jobs: 'server/**' in .github/workflows/docker.yml (line 45), 'server/**' in .github/workflows/test.yml (line 46)
PASS  K2  Byte-span confinement: 0 specifier spans changed in 0 files; every other byte identical (0.0 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 0 rewritten specifiers keep their form (1.9 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (6.7 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.8 s)
PASS  K4  Location scan: 0 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (0 findings in docs, comments or ungated coverage settings) (0.3 s)
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (48.6 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.7 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e
PASS  K8  Oracles on the commit: tsc exit 0; unit 105/105 files and 2,337/2,337 cases equal to base (head: 105/105 files load, 2,337 passed, 0 failed, 0 skipped); openapi byte-identical to the base's open-api/immich-openapi-specs.json (947,932 bytes) (170.7 s)

verdict: PASS (static checks and oracles)
digest: sha256:c57590c655d8e83e44aea69fd39c09d701371379e702c6accd4c097bb2f7c0ec

The whole PR

Whole-PR certificate: PASS (static checks and oracles) certificate.json

certificate JSON · digest sha256:9a5b2404631c2ac668462ad93fcbcd116637244e2b4f76e987bcc4e23e8be2b5

ac certify 02063972e8..c4be040b57 (package root server/), profile immich
trees: 424df72c34..4e457bb4e8
pathMap: 367 moves, 180 edited in place, 2917 unchanged, 2 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 367 moved files (0.2 s)
PASS  K1  Move-set integrity: 367 moves, 180 files edited in place, 2 inert tool configs added, nothing else added or deleted (8.3 s)
        finding (tool-config-added) server/.dependency-cruiser-known-violations.json: added at the package root and proven inert: in no tsconfig program, loaded by no reference, packed by no published package, named or globbed by no other file, and the tool runs nowhere; CI path filters match it, so it triggers their jobs: 'server/**' in .github/workflows/docker.yml (line 45), 'server/**' in .github/workflows/test.yml (line 46)
        finding (tool-config-added) server/.dependency-cruiser.json: added at the package root and proven inert: in no tsconfig program, loaded by no reference, packed by no published package, named or globbed by no other file, and the tool runs nowhere; CI path filters match it, so it triggers their jobs: 'server/**' in .github/workflows/docker.yml (line 45), 'server/**' in .github/workflows/test.yml (line 46)
PASS  K2  Byte-span confinement: 2474 specifier spans changed in 515 files; every other byte identical (3.4 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 2474 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (5.1 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.7 s)
PASS  K4  Location scan: 367 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (13 findings in docs, comments or ungated coverage settings) (5.7 s)
        finding (stack-text) server/src/repositories/metadata.repository.ts: moved to server/src/platform/metadata/metadata.repository.ts; 1 stack-trace reads passed along as text (line 133); their frames now name the new path
        finding (stack-text) server/src/repositories/websocket.repository.ts: moved to server/src/platform/websocket/websocket.repository.ts; 1 stack-trace reads passed along as text (line 95); their frames now name the new path
        finding (stack-text) server/src/services/asset-media.service.ts: moved to server/src/modules/asset/asset-media.service.ts; 1 stack-trace reads passed along as text (line 224); their frames now name the new path
        … 23 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (0.0 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e
PASS  K8  Oracles on the commit: tsc exit 0; unit 105/105 files and 2,337/2,337 cases equal to base (head: 105/105 files load, 2,337 passed, 0 failed, 0 skipped); openapi byte-identical to the base's open-api/immich-openapi-specs.json (947,932 bytes) (114.9 s)

verdict: PASS (static checks and oracles)
digest: sha256:9a5b2404631c2ac668462ad93fcbcd116637244e2b4f76e987bcc4e23e8be2b5

Findings: recorded, never fixed

A good restructure makes existing bugs obvious; fixing them is never part of it. These 45 findings were found by deterministic collectors and are left exactly as they are in the code.

Narration: Nemotron 3.5 Lightning (thinking off) (nvidia/Nemotron-3_5-Lightning), 2 calls, $0.0010 when recorded, replayed here; 35 findings narrated of the 40 findings sent (5 more were not sent: the narration takes the first 40); 4 narrations dropped by the lexical guard (a narration may only restate its evidence), 1 finding with no narration returned by the model.

Findings sent without a narration
FindingWhy
F-68921a0c7282dropped by the guard: names "server/src/repositories/database.repository.ts", which the evidence doesn't contain
F-a1ef2439353bdropped by the guard: names "relocated", which the evidence doesn't contain
F-ab4403001c97dropped by the guard: names "relocated", which the evidence doesn't contain
F-ab71273b30cedropped by the guard: names "relocated", which the evidence doesn't contain
F-70d9e19108a1no narration returned
Sources
SourceWhat it contributed
targetfacts at 02063972e8: 269 movable files, 1759 edges, 269 placed by the plan
boundariesboundaries/report.json: 2 strongly connected sets, 8 back-edges
facts3 tables with writers in several groups, 1 god-injection base classes
analyzer458 production files analyzed, 0 import test code
validator10 warnings on the run's plan
certificate67 certificates read (steps, rungs, whole PR)
run107 run.json findings

module-cycle (2)

42 folders form one import cycle F-f375142329cd

The R4 report shows that 42 out of 73 folders are strongly connected through imports, each reaching every other. With 328 edges over 1025 files inside the set, these 91 edges spanning 174 files are the only back-edges that close the cycles; removing them leaves the collection acyclic. (narration: Nemotron 3.5 Lightning)

Evidence
42 of 73 folders are strongly connected (from R4's boundary report (boundaries/report.json)): each reaches every other through imports.
Members: module/album, module/asset, module/auth, module/config, module/database-backup, module/job, module/library, module/machine-learning, module/maintenance, module/map, module/ocr, module/partner, module/person, module/plugin, module/queue, module/search, module/server, module/session, module/shared-link, module/system-metadata, module/tag, module/user, module/version, module/workflow, other:src, other:src/maintenance, other:src/repositories, other:src/schema, other:src/schema/tables, other:src/services, other:src/utils, platform/access, platform/cron, platform/database, platform/event, platform/file, platform/http-response, platform/logging, platform/media, platform/move, platform/storage, shared.
Inside the set: 328 edges between them over 1025 files. These 91 edges (174 files) close every cycle (R4's back-edges first); without them the set is acyclic:
- other:src/schema/tables → other:src/schema (21 files, e.g. server/src/schema/tables/album-asset.table.ts → server/src/schema/functions.ts)
- module/person → module/asset (6 files, e.g. server/src/modules/person/person.controller.ts → server/src/modules/asset/asset-ids.response.dto.ts)
- module/album → module/asset (5 files, e.g. server/src/modules/album/album.controller.ts → server/src/modules/asset/asset-ids.response.dto.ts)
- module/search → module/asset (5 files, e.g. server/src/modules/search/search.controller.ts → server/src/modules/asset/asset-response.dto.ts)
- module/shared-link → module/asset (5 files, e.g. server/src/modules/shared-link/shared-link.controller.ts → server/src/modules/asset/asset-ids.response.dto.ts)
- platform/database → other:src/schema/tables (5 files, e.g. server/src/platform/database/database.ts → server/src/schema/tables/album.table.ts)
- module/auth → module/user (4 files, e.g. server/src/modules/auth/auth.controller.ts → server/src/modules/user/user.dto.ts)
- module/user → module/asset (4 files, e.g. server/src/modules/user/user-admin.controller.ts → server/src/modules/asset/asset.dto.ts)
- platform/access → module/person (4 files, e.g. server/src/platform/access/access.repository.ts → server/src/modules/person/person.dto.ts)
- platform/media → module/asset (4 files, e.g. server/src/platform/media/media.repository.ts → server/src/modules/asset/editing.dto.ts)
- module/album → other:src/schema/tables (3 files, e.g. server/src/modules/album/album-user.repository.ts → server/src/schema/tables/album-user.table.ts)
- module/server → module/user (3 files, e.g. server/src/modules/server/server.controller.ts → server/src/modules/user/license.dto.ts)
- module/shared-link → other:src/schema/tables (3 files, e.g. server/src/modules/shared-link/shared-link.repository.ts → server/src/schema/tables/asset-exif.table.ts)
- module/tag → module/asset (3 files, e.g. server/src/modules/tag/tag.controller.ts → server/src/modules/asset/asset-ids.response.dto.ts)
- platform/file → module/asset (3 files, e.g. server/src/platform/file/file-upload.interceptor.ts → server/src/modules/asset/asset-media.dto.ts)
- … 76 more edges (96 files)

Files: server/src/modules/album/album-user.repository.ts server/src/modules/album/album.controller.ts server/src/modules/asset/asset-ids.response.dto.ts server/src/modules/asset/asset-media.dto.ts server/src/modules/asset/asset-response.dto.ts server/src/modules/asset/asset.dto.ts server/src/modules/asset/editing.dto.ts server/src/modules/auth/auth.controller.ts and 19 more

Source: boundaries

module/notification and other:src/emails import each other F-848cb161117b

Module notification and other:src/emails are strongly connected, each reaching the other through imports; one edge over four files closes the cycle, and removing it makes the set acyclic. (narration: Nemotron 3.5 Lightning)

Evidence
2 of 73 folders are strongly connected (from R4's boundary report (boundaries/report.json)): each reaches every other through imports.
Members: module/notification, other:src/emails.
Inside the set: 2 edges between them over 8 files. These 1 edges (4 files) close every cycle (R4's back-edges first); without them the set is acyclic:
- other:src/emails → module/notification (4 files, e.g. server/src/emails/album-invite.email.tsx → server/src/modules/notification/email.repository.ts)

Files: server/src/emails/album-invite.email.tsx server/src/modules/notification/email.repository.ts

Source: boundaries

god-injection (1)

BaseService injects 56 members into 51 classes F-190847636c3d

BaseService receives 56 constructor-injected members, and 51 classes extend it so each inherits all 56; on average a subclass reads 5.7 of them, and the most-read members such as logger and repositories are accessed by many classes. (narration: Nemotron 3.5 Lightning)

Evidence
BaseService (server/src/services/base.service.ts) takes 56 constructor-injected members (56 of them repositories), and 51 classes extend it, so each receives all 56.
Each subclass reads 5.7 of them on average through this.<member> (median 5, min 1, max 15 in MetadataService); every member has a reader.
Most read: logger (33 classes), jobRepository (23 classes), assetRepository (21 classes), eventRepository (18 classes), userRepository (18 classes).
Per class (members read of 56):
- MetadataService (server/src/services/metadata.service.ts): 15 (albumRepository, assetJobRepository, assetRepository, cryptoRepository, databaseRepository, eventRepository, jobRepository, logger, … 7 more)
- PersonService (server/src/services/person.service.ts): 15 (assetJobRepository, assetRepository, clusterGroupRepository, cryptoRepository, databaseRepository, jobRepository, logger, machineLearningRepository, … 7 more)
- AssetService (server/src/services/asset.service.ts): 13 (albumRepository, assetEditRepository, assetJobRepository, assetRepository, eventRepository, jobRepository, logger, ocrRepository, … 5 more)
- AuthService (server/src/services/auth.service.ts): 10 (apiKeyRepository, cryptoRepository, eventRepository, jobRepository, logger, mediaRepository, oauthRepository, sessionRepository, … 2 more)
- LibraryService (server/src/services/library.service.ts): 10 (assetJobRepository, assetRepository, cronRepository, cryptoRepository, databaseRepository, eventRepository, jobRepository, libraryRepository, … 2 more)
- UserService (server/src/services/user.service.ts): 10 (albumRepository, assetRepository, configRepository, cryptoRepository, eventRepository, jobRepository, logger, mediaRepository, … 2 more)
- CliService (server/src/services/cli.service.ts): 9 (appRepository, assetRepository, cryptoRepository, databaseRepository, personRepository, sessionRepository, storageRepository, systemMetadataRepository, … 1 more)
- DuplicateService (server/src/services/duplicate.service.ts): 9 (albumRepository, assetJobRepository, assetRepository, cryptoRepository, duplicateRepository, eventRepository, jobRepository, logger, … 1 more)
- IntegrityService (server/src/services/integrity.service.ts): 9 (assetRepository, cronRepository, databaseRepository, eventRepository, integrityRepository, jobRepository, logger, storageRepository, … 1 more)
- NotificationService (server/src/services/notification.service.ts): 9 (albumRepository, assetJobRepository, assetRepository, emailRepository, jobRepository, logger, notificationRepository, userRepository, … 1 more)
- VersionService (server/src/services/version.service.ts): 9 (configRepository, cronRepository, databaseRepository, jobRepository, logger, serverInfoRepository, systemMetadataRepository, versionRepository, … 1 more)
- MediaService (server/src/services/media.service.ts): 8 (assetJobRepository, assetRepository, jobRepository, logger, mediaRepository, ocrRepository, personRepository, storageRepository)
- MemoryService (server/src/services/memory.service.ts): 8 (accessRepository, assetRepository, databaseRepository, logger, memoryRepository, personRepository, systemMetadataRepository, userRepository)
- StorageTemplateService (server/src/services/storage-template.service.ts): 8 (albumRepository, assetJobRepository, databaseRepository, jobRepository, logger, moveRepository, storageRepository, userRepository)
- UserAdminService (server/src/services/user-admin.service.ts): 8 (albumRepository, assetRepository, cryptoRepository, eventRepository, jobRepository, logger, sessionRepository, userRepository)
- WorkflowExecutionService (server/src/services/workflow-execution.service.ts): 8 (configRepository, cryptoRepository, databaseRepository, jobRepository, logger, pluginRepository, storageRepository, workflowRepository)
- AlbumService (server/src/services/album.service.ts): 7 (accessRepository, albumRepository, albumUserRepository, eventRepository, logger, mapRepository, userRepository)
- AssetMediaService (server/src/services/asset-media.service.ts): 7 (albumRepository, assetRepository, eventRepository, jobRepository, logger, sharedLinkRepository, storageRepository)
- ServerService (server/src/services/server.service.ts): 7 (configRepository, cryptoRepository, logger, serverInfoRepository, storageRepository, systemMetadataRepository, userRepository)
- JobService (server/src/services/job.service.ts): 6 (assetEditRepository, assetRepository, eventRepository, jobRepository, logger, websocketRepository)
- OcrService (server/src/services/ocr.service.ts): 6 (assetJobRepository, assetRepository, jobRepository, logger, machineLearningRepository, ocrRepository)
- SmartInfoService (server/src/services/smart-info.service.ts): 6 (assetJobRepository, databaseRepository, jobRepository, logger, machineLearningRepository, searchRepository)
- StorageService (server/src/services/storage.service.ts): 6 (assetRepository, configRepository, databaseRepository, logger, storageRepository, systemMetadataRepository)
- TranscodingService (server/src/services/transcoding.service.ts): 6 (databaseRepository, logger, processRepository, storageRepository, videoStreamRepository, websocketRepository)
- ClusterGroupService (server/src/services/cluster-group.service.ts): 5 (clusterGroupRepository, eventRepository, jobRepository, personRepository, userRepository)
- DownloadService (server/src/services/download.service.ts): 5 (assetRepository, downloadRepository, logger, storageRepository, userRepository)
- MaintenanceService (server/src/services/maintenance.service.ts): 5 (appRepository, eventRepository, logger, storageRepository, systemMetadataRepository)
- QueueService (server/src/services/queue.service.ts): 5 (cronRepository, databaseRepository, eventRepository, jobRepository, logger)
- SearchService (server/src/services/search.service.ts): 5 (assetRepository, machineLearningRepository, partnerRepository, personRepository, searchRepository)
- TagService (server/src/services/tag.service.ts): 5 (accessRepository, assetRepository, eventRepository, jobRepository, tagRepository)
- HlsService (server/src/services/hls.service.ts): 4 (cryptoRepository, storageRepository, videoStreamRepository, websocketRepository)
- SharedLinkService (server/src/services/shared-link.service.ts): 4 (cryptoRepository, logger, sharedLinkAssetRepository, sharedLinkRepository)
- SyncService (server/src/services/sync.service.ts): 4 (logger, sessionRepository, syncCheckpointRepository, syncRepository)
- SystemConfigService (server/src/services/system-config.service.ts): 4 (configRepository, eventRepository, logger, machineLearningRepository)
- TrashService (server/src/services/trash.service.ts): 4 (eventRepository, jobRepository, logger, trashRepository)
- DatabaseService (server/src/services/database.service.ts): 3 (configRepository, databaseRepository, logger)
- MapService (server/src/services/map.service.ts): 3 (albumRepository, mapRepository, partnerRepository)
- NotificationAdminService (server/src/services/notification-admin.service.ts): 3 (emailRepository, notificationRepository, userRepository)
- PartnerService (server/src/services/partner.service.ts): 3 (logger, partnerRepository, userRepository)
- SessionService (server/src/services/session.service.ts): 3 (cryptoRepository, logger, sessionRepository)
- StackService (server/src/services/stack.service.ts): 3 (assetRepository, eventRepository, stackRepository)
- ApiKeyService (server/src/services/api-key.service.ts): 2 (apiKeyRepository, cryptoRepository)
- AssetFileService (server/src/services/asset-file.service.ts): 2 (assetFileRepository, jobRepository)
- TelemetryService (server/src/services/telemetry.service.ts): 2 (telemetryRepository, userRepository)
- TimelineService (server/src/services/timeline.service.ts): 2 (assetRepository, partnerRepository)
- WorkflowService (server/src/services/workflow.service.ts): 2 (pluginRepository, workflowRepository)
- ActivityService (server/src/services/activity.service.ts): 1 (activityRepository)
- AuthAdminService (server/src/services/auth-admin.service.ts): 1 (userRepository)
- PluginService (server/src/services/plugin.service.ts): 1 (pluginRepository)
- SystemMetadataService (server/src/services/system-metadata.service.ts): 1 (systemMetadataRepository)
- ViewService (server/src/services/view.service.ts): 1 (viewRepository)

Files: server/src/services/activity.service.ts server/src/services/album.service.ts server/src/services/api-key.service.ts server/src/services/asset-file.service.ts server/src/services/asset-media.service.ts server/src/services/asset.service.ts server/src/services/auth-admin.service.ts server/src/services/auth.service.ts and 44 more

Source: facts

multi-writer-table (3)

Table asset is written by 4 groups F-471f7dbe2fc2

The table asset is written by four files located in four separate plan groups: module/asset, module/duplicate, module/stack, and module/trash. (narration: Nemotron 3.5 Lightning)

Evidence
Table asset is written by 4 files in 4 plan groups (and read by 23 files in 22 groups):
- module/asset: server/src/repositories/asset.repository.ts
- module/duplicate: server/src/repositories/duplicate.repository.ts
- module/stack: server/src/repositories/stack.repository.ts
- module/trash: server/src/repositories/trash.repository.ts

Files: server/src/repositories/asset.repository.ts server/src/repositories/duplicate.repository.ts server/src/repositories/stack.repository.ts server/src/repositories/trash.repository.ts

Source: facts

Table cluster_group is written by 2 groups F-bdcfcf0f1886

Table cluster_group is written by two files in two plan groups: module/cluster-group and module/person. (narration: Nemotron 3.5 Lightning)

Evidence
Table cluster_group is written by 2 files in 2 plan groups:
- module/cluster-group: server/src/repositories/cluster-group.repository.ts
- module/person: server/src/repositories/person.repository.ts

Files: server/src/repositories/cluster-group.repository.ts server/src/repositories/person.repository.ts

Source: facts

Table session_sync_checkpoint is written by 2 groups F-e7b889cd5d1e

Table session_sync_checkpoint is written by two files in two plan groups (module/session and module/sync) and read by one file in one group. (narration: Nemotron 3.5 Lightning)

Evidence
Table session_sync_checkpoint is written by 2 files in 2 plan groups (and read by 1 file in 1 group):
- module/session: server/src/repositories/session.repository.ts
- module/sync: server/src/repositories/sync-checkpoint.repository.ts

Files: server/src/repositories/session.repository.ts server/src/repositories/sync-checkpoint.repository.ts

Source: facts

back-edge (8)

Back-edge module/auth → module/user F-0f4709d1dd31

Module auth imports module user in four files, which violates the allow-list encoded in R4's module order; R4's baseline records this as a known violation. (narration: Nemotron 3.5 Lightning)

Evidence
module/auth imports module/user in 4 files, against the module order R4's allow-list encodes; R4's baseline freezes it as a known violation.
- server/src/modules/auth/auth.controller.ts → server/src/modules/user/user.dto.ts
- server/src/modules/auth/auth.service.ts → server/src/modules/user/profile-image.ts
- server/src/modules/auth/auth.service.ts → server/src/modules/user/user.dto.ts

Files: server/src/modules/auth/auth.controller.ts server/src/modules/auth/auth.service.ts server/src/modules/user/profile-image.ts server/src/modules/user/user.dto.ts

Source: boundaries

Back-edge module/user → module/asset F-d23785863ced

Module user imports module asset in four files, which violates the allow-list encoded in R4's module order; R4's baseline records this as a known violation. (narration: Nemotron 3.5 Lightning)

Evidence
module/user imports module/asset in 4 files, against the module order R4's allow-list encodes; R4's baseline freezes it as a known violation.
- server/src/modules/user/user-admin.controller.ts → server/src/modules/asset/asset.dto.ts
- server/src/modules/user/user-admin.service.ts → server/src/modules/asset/asset.dto.ts
- server/src/modules/user/user-methods.ts → server/src/modules/asset/asset.repository.ts

Files: server/src/modules/asset/asset.dto.ts server/src/modules/asset/asset.repository.ts server/src/modules/user/user-admin.controller.ts server/src/modules/user/user-admin.service.ts server/src/modules/user/user-methods.ts

Source: boundaries

Back-edge module/tag → module/asset F-8dbbbf14f9f3

Three files under module/tag import module/asset, but R4's allow-list does not permit this dependency. R4's baseline marks these as known violations that remain unchanged. (narration: Nemotron 3.5 Lightning)

Evidence
module/tag imports module/asset in 3 files, against the module order R4's allow-list encodes; R4's baseline freezes it as a known violation.
- server/src/modules/tag/tag.controller.ts → server/src/modules/asset/asset-ids.response.dto.ts
- server/src/modules/tag/tag.service.ts → server/src/modules/asset/asset-ids.response.dto.ts
- server/src/modules/tag/tag.service.ts → server/src/modules/asset/asset.util.ts

Files: server/src/modules/asset/asset-ids.response.dto.ts server/src/modules/asset/asset.util.ts server/src/modules/tag/tag.controller.ts server/src/modules/tag/tag.service.ts

Source: boundaries

Back-edge module/plugin → module/workflow F-834724fcbf9e

Two files under module/plugin import module/workflow, but R4's allow-list does not allow this. R4's baseline records these as known violations. (narration: Nemotron 3.5 Lightning)

Evidence
module/plugin imports module/workflow in 2 files, against the module order R4's allow-list encodes; R4's baseline freezes it as a known violation.
- server/src/modules/plugin/plugin.dto.ts → server/src/modules/workflow/workflow.ts
- server/src/modules/plugin/plugin.service.ts → server/src/modules/workflow/workflow.ts

Files: server/src/modules/plugin/plugin.dto.ts server/src/modules/plugin/plugin.service.ts server/src/modules/workflow/workflow.ts

Source: boundaries

Back-edge module/database-backup → module/maintenance F-6a82ccadb707

One file under module/database-backup imports module/maintenance, which R4's allow-list forbids. R4's baseline records this as a known violation. (narration: Nemotron 3.5 Lightning)

Evidence
module/database-backup imports module/maintenance in 1 files, against the module order R4's allow-list encodes; R4's baseline freezes it as a known violation.
- server/src/modules/database-backup/database-backup.controller.ts → server/src/modules/maintenance/maintenance.service.ts

Files: server/src/modules/database-backup/database-backup.controller.ts server/src/modules/maintenance/maintenance.service.ts

Source: boundaries

Back-edge module/version → module/server F-86474a013374

One file under module/version imports module/server, which R4's allow-list disallows. R4's baseline records this as a known violation. (narration: Nemotron 3.5 Lightning)

Evidence
module/version imports module/server in 1 files, against the module order R4's allow-list encodes; R4's baseline freezes it as a known violation.
- server/src/modules/version/version.service.ts → server/src/modules/server/server.dto.ts

Files: server/src/modules/server/server.dto.ts server/src/modules/version/version.service.ts

Source: boundaries

Back-edge module/asset → module/person F-bdf320395cbd

One file under module/asset imports module/person, which R4's allow-list forbids. R4's baseline records this as a known violation. (narration: Nemotron 3.5 Lightning)

Evidence
module/asset imports module/person in 1 files, against the module order R4's allow-list encodes; R4's baseline freezes it as a known violation.
- server/src/modules/asset/asset-response.dto.ts → server/src/modules/person/person.dto.ts

Files: server/src/modules/asset/asset-response.dto.ts server/src/modules/person/person.dto.ts

Source: boundaries

Back-edge module/auth → module/config F-ddff071a1b0b

One file under module/auth imports module/config, which R4's allow-list disallows. R4's baseline records this as a known violation. (narration: Nemotron 3.5 Lightning)

Evidence
module/auth imports module/config in 1 files, against the module order R4's allow-list encodes; R4's baseline freezes it as a known violation.
- server/src/modules/auth/auth.service.ts → server/src/modules/config/config.dto.ts

Files: server/src/modules/auth/auth.service.ts server/src/modules/config/config.dto.ts

Source: boundaries

stack-text (12)

Stack-trace text names moved paths (K4): server/src/services/metadata.service.ts F-49561c40d405

In server/src/services/metadata.service.ts a stack-trace text at line 170 now names the new path after the file was moved to server/src/platform/metadata/metadata.service.ts; two stack-trace reads passed along as text recorded three times. (narration: Nemotron 3.5 Lightning)

Evidence
K4 reported one finding in server/src/services/metadata.service.ts, 3 times (step 51, certificate.json, rungs/R2.json):
- moved to server/src/platform/metadata/metadata.service.ts; 2 stack-trace reads passed along as text (line 170); their frames now name the new path (step 51, certificate.json, rungs/R2.json)

Files: server/src/services/metadata.service.ts

Source: certificate; steps 51; certificates certificate.json, rungs/R2.json

Stack-trace text names moved paths (K4): server/src/services/workflow-execution.service.ts F-6ab2e0a4c68b

In server/src/services/workflow-execution.service.ts line 197, a stack-trace text now names the new path after the file moved to server/src/modules/workflow/workflow-execution.service.ts; one stack-trace read passed along as text recorded three times. (narration: Nemotron 3.5 Lightning)

Evidence
K4 reported one finding in server/src/services/workflow-execution.service.ts, 3 times (step 38, certificate.json, rungs/R1.json):
- moved to server/src/modules/workflow/workflow-execution.service.ts; 1 stack-trace reads passed along as text (line 197); their frames now name the new path (step 38, certificate.json, rungs/R1.json)

Files: server/src/services/workflow-execution.service.ts

Source: certificate; steps 38; certificates certificate.json, rungs/R1.json

Stack-trace text names moved paths (K4): server/src/services/auth.service.ts F-991694f69a68

Stack-trace text in one file still references the old path of auth.service.ts after its move; the frames now use the new module location. (narration: Nemotron 3.5 Lightning)

Evidence
K4 reported one finding in server/src/services/auth.service.ts, 3 times (step 5, certificate.json, rungs/R1.json):
- moved to server/src/modules/auth/auth.service.ts; 1 stack-trace reads passed along as text (line 403); their frames now name the new path (step 5, certificate.json, rungs/R1.json)

Files: server/src/services/auth.service.ts

Source: certificate; steps 5; certificates certificate.json, rungs/R1.json

Stack-trace text names moved paths (K4): server/src/repositories/websocket.repository.ts F-a1ef2439353b

Evidence
K4 reported one finding in server/src/repositories/websocket.repository.ts, 3 times (step 58, certificate.json, rungs/R2.json):
- moved to server/src/platform/websocket/websocket.repository.ts; 1 stack-trace reads passed along as text (line 95); their frames now name the new path (step 58, certificate.json, rungs/R2.json)

Files: server/src/repositories/websocket.repository.ts

Source: certificate; steps 58; certificates certificate.json, rungs/R2.json

Stack-trace text names moved paths (K4): server/src/services/person.service.ts F-a3f6cf654776

Two stack-trace reads in person.service.ts reference the moved path after the module relocation. (narration: Nemotron 3.5 Lightning)

Evidence
K4 reported one finding in server/src/services/person.service.ts, 3 times (step 21, certificate.json, rungs/R1.json):
- moved to server/src/modules/person/person.service.ts; 2 stack-trace reads passed along as text (line 321); their frames now name the new path (step 21, certificate.json, rungs/R1.json)

Files: server/src/services/person.service.ts

Source: certificate; steps 21; certificates certificate.json, rungs/R1.json

Stack-trace text names moved paths (K4): server/src/services/notification.service.ts F-a9fafedd2e0c

Two stack-trace reads in notification.service.ts now name the moved service path after the module relocation. (narration: Nemotron 3.5 Lightning)

Evidence
K4 reported one finding in server/src/services/notification.service.ts, 3 times (step 18, certificate.json, rungs/R1.json):
- moved to server/src/modules/notification/notification.service.ts; 2 stack-trace reads passed along as text (line 88); their frames now name the new path (step 18, certificate.json, rungs/R1.json)

Files: server/src/services/notification.service.ts

Source: certificate; steps 18; certificates certificate.json, rungs/R1.json

Stack-trace text names moved paths (K4): server/src/services/duplicate.service.ts F-ab4403001c97

Evidence
K4 reported one finding in server/src/services/duplicate.service.ts, 3 times (step 10, certificate.json, rungs/R1.json):
- moved to server/src/modules/duplicate/duplicate.service.ts; 1 stack-trace reads passed along as text (line 104); their frames now name the new path (step 10, certificate.json, rungs/R1.json)

Files: server/src/services/duplicate.service.ts

Source: certificate; steps 10; certificates certificate.json, rungs/R1.json

Stack-trace text names moved paths (K4): server/src/services/storage-template.service.ts F-ab71273b30ce

Evidence
K4 reported one finding in server/src/services/storage-template.service.ts, 3 times (step 55, certificate.json, rungs/R2.json):
- moved to server/src/platform/storage/storage-template.service.ts; 1 stack-trace reads passed along as text (line 263); their frames now name the new path (step 55, certificate.json, rungs/R2.json)

Files: server/src/services/storage-template.service.ts

Source: certificate; steps 55; certificates certificate.json, rungs/R2.json

Stack-trace text names moved paths (K4): server/src/utils/logger.ts F-b5d99548eaf9

One stack-trace in logger.ts reads passed-along text that now names the relocated utility path. (narration: Nemotron 3.5 Lightning)

Evidence
K4 reported one finding in server/src/utils/logger.ts, 3 times (step 49, certificate.json, rungs/R2.json):
- moved to server/src/platform/logging/logger.ts; 1 stack-trace reads passed along as text (line 24); their frames now name the new path (step 49, certificate.json, rungs/R2.json)

Files: server/src/utils/logger.ts

Source: certificate; steps 49; certificates certificate.json, rungs/R2.json

Stack-trace text names moved paths (K4): server/src/repositories/metadata.repository.ts F-cd5da954f0ed

Evidence
K4 reported one finding in server/src/repositories/metadata.repository.ts, 3 times (step 51, certificate.json, rungs/R2.json):
- moved to server/src/platform/metadata/metadata.repository.ts; 1 stack-trace reads passed along as text (line 133); their frames now name the new path (step 51, certificate.json, rungs/R2.json)

Files: server/src/repositories/metadata.repository.ts

Source: certificate; steps 51; certificates certificate.json, rungs/R2.json

Stack-trace text names moved paths (K4): server/src/services/asset-media.service.ts F-d7f70626dd55

Evidence
K4 reported one finding in server/src/services/asset-media.service.ts, 3 times (step 4, certificate.json, rungs/R1.json):
- moved to server/src/modules/asset/asset-media.service.ts; 1 stack-trace reads passed along as text (line 224); their frames now name the new path (step 4, certificate.json, rungs/R1.json)

Files: server/src/services/asset-media.service.ts

Source: certificate; steps 4; certificates certificate.json, rungs/R1.json

Stack-trace text names moved paths (K4): server/src/services/version.service.ts F-dad88f8446e6

Evidence
K4 reported one finding in server/src/services/version.service.ts, 3 times (step 35, certificate.json, rungs/R1.json):
- moved to server/src/modules/version/version.service.ts; 1 stack-trace reads passed along as text (line 140); their frames now name the new path (step 35, certificate.json, rungs/R1.json)

Files: server/src/services/version.service.ts

Source: certificate; steps 35; certificates certificate.json, rungs/R1.json

plan-warning (10)

Plan warning (one-file-platform): platform/http-client F-14d96dec2313

The platform/http-client group in plan.yaml contains only one file and no other planned group uses it, so the one-file-platform rule flags it for possible folding. (narration: Nemotron 3.5 Lightning)

Evidence
The plan validator's rule one-file-platform, on the run's plan.yaml (group platform/http-client): platform/http-client holds one file, and no other planned group uses it: consider folding it into the concern or feature it serves

Files: server/src/utils/fetch.ts

Source: validator

Plan warning (one-file-platform): platform/check F-175fe3a4820a

The platform/check group in plan.yaml contains only one file and no other planned group uses it, so the one-file-platform rule flags it for possible folding. (narration: Nemotron 3.5 Lightning)

Evidence
The plan validator's rule one-file-platform, on the run's plan.yaml (group platform/check): platform/check holds one file, and no other planned group uses it: consider folding it into the concern or feature it serves

Files: server/src/commands/schema-check.ts

Source: validator

Plan warning (singleton-group): module/machine-learning F-545a4b88a62f

Rule singleton-group flags module/machine-learning because the plan holds only one file in that group. (narration: Nemotron 3.5 Lightning)

Evidence
The plan validator's rule singleton-group, on the run's plan.yaml (group module/machine-learning): module/machine-learning holds one file

Files: server/src/repositories/machine-learning.repository.ts

Source: validator

Plan warning (unsupported-merge): module/auth F-692ad4017c11

Plan rule unsupported-merge reports that module/auth has a draft group "grant" with no shared word, edge, table or route. (narration: Nemotron 3.5 Lightning)

Evidence
The plan validator's rule unsupported-merge, on the run's plan.yaml (group module/auth): module/auth takes draft group "grant" (src/commands/grant-admin.ts): no shared word, edge, table or route

Source: validator

Plan warning (platform-feature): platform/move F-6dc722024105

Rule platform-feature on group platform/move notes that move.repository.ts writes to table move_history, classifying it as a feature rather than plumbing. (narration: Nemotron 3.5 Lightning)

Evidence
The plan validator's rule platform-feature, on the run's plan.yaml (group platform/move): src/repositories/move.repository.ts writes tables (move_history): a feature, not plumbing

Files: server/src/repositories/move.repository.ts

Source: validator

Plan warning (one-file-platform): platform/move F-af06f12438b8

Rule one-file-platform on group platform/move flags that the group holds a single file used only by platform/storage, suggesting a potential fold. (narration: Nemotron 3.5 Lightning)

Evidence
The plan validator's rule one-file-platform, on the run's plan.yaml (group platform/move): platform/move holds one file, and only platform/storage uses it: consider folding it there

Files: server/src/repositories/move.repository.ts

Source: validator

Plan warning (platform-feature): platform/bootstrap F-e1c975dc8064

Rule platform-feature on group platform/bootstrap notes that app.controller.ts serves routes, classifying it as a feature rather than plumbing. (narration: Nemotron 3.5 Lightning)

Evidence
The plan validator's rule platform-feature, on the run's plan.yaml (group platform/bootstrap): src/controllers/app.controller.ts serves routes: a feature, not plumbing

Files: server/src/controllers/app.controller.ts

Source: validator

Plan warning (impure-shared): shared/shared F-e3b63d08f742

Rule impure-shared on group shared/shared flags that src/services/api.service.ts is a service, while shared/ should hold only pure code. (narration: Nemotron 3.5 Lightning)

Evidence
The plan validator's rule impure-shared, on the run's plan.yaml (group shared/shared): src/services/api.service.ts is a service; shared/ holds pure code only

Files: server/src/services/api.service.ts

Source: validator

Plan warning (one-file-platform): platform/transcoding F-fa4aa2cae116

Evidence
The plan validator's rule one-file-platform, on the run's plan.yaml (group platform/transcoding): platform/transcoding holds one file, and no other planned group uses it: consider folding it into the concern or feature it serves

Files: server/src/services/transcoding.service.ts

Source: validator

Plan warning (unsupported-merge): module/auth F-ff0edb54f50f

Evidence
The plan validator's rule unsupported-merge, on the run's plan.yaml (group module/auth): module/auth takes draft group "password-login" (src/commands/password-login.ts): no shared word, edge, table or route

Source: validator

old-path-in-docs (3)

Docs name old paths (K4): docs/docs/developer/architecture.mdx F-68921a0c7282

Evidence
K4 reported 3 distinct findings in docs/docs/developer/architecture.mdx, 138 times (steps 1–40, 42–45, 49–59, certificate.json, rungs/R1.json, rungs/R2.json):
- line 60: 'src/repositories' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/activity.repository.ts (moved to server/src/modules/activity/activity.repository.ts) (steps 1–6, 9–22, 24–31, 33–39, 42–43, 45, 49–56, 58, certificate.json, rungs/R1.json, rungs/R2.json)
- line 60: 'src/services' is the directory server/src/services, whose contents change with the move of server/src/services/activity.service.spec.ts (moved to server/src/modules/activity/activity.service.spec.ts) (steps 1–13, 15–38, 44, 50–51, 54–57, 59, certificate.json, rungs/R1.json, rungs/R2.json)
- line 64: 'src/controllers' is the directory server/src/controllers, whose contents change with the move of server/src/controllers/activity.controller.spec.ts (moved to server/src/modules/activity/activity.controller.spec.ts) (steps 1–13, 15–18, 20–34, 36–38, 40, 54, certificate.json, rungs/R1.json, rungs/R2.json)

Files: docs/docs/developer/architecture.mdx

Source: certificate; steps 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 42, 43, 44, 45, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59; certificates certificate.json, rungs/R1.json, rungs/R2.json

Docs name old paths (K4): .github/pull_request_template.md F-8759fa26d236

The pull request template references three directories (src/services, src/repositories, and again src/services) whose contents change as files move to module folders, recorded 146 times across steps and rung JSON files. (narration: Nemotron 3.5 Lightning)

Evidence
K4 reported 3 distinct findings in .github/pull_request_template.md, 146 times (steps 1–39, 42–45, 49–59, certificate.json, rungs/R1.json, rungs/R2.json):
- line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/activity.service.spec.ts (moved to server/src/modules/activity/activity.service.spec.ts) (steps 1–13, 15–38, 44, 50–51, 54–57, 59, certificate.json, rungs/R1.json, rungs/R2.json)
- line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/activity.repository.ts (moved to server/src/modules/activity/activity.repository.ts) (steps 1–6, 9–22, 24–31, 33–39, 42–43, 45, 49–56, 58, certificate.json, rungs/R1.json, rungs/R2.json)
- line 37: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/activity.service.spec.ts (moved to server/src/modules/activity/activity.service.spec.ts) (steps 1–13, 15–38, 44, 50–51, 54–57, 59, certificate.json, rungs/R1.json, rungs/R2.json)

Files: .github/pull_request_template.md

Source: certificate; steps 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 42, 43, 44, 45, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59; certificates certificate.json, rungs/R1.json, rungs/R2.json

Docs name old paths (K4): docs/docs/features/supported-formats.md F-b033494c9d5b

Docs reference the old path for mime-types.ts in three locations; the refactoring left the outdated path intact in documentation. (narration: Nemotron 3.5 Lightning)

Evidence
K4 reported one finding in docs/docs/features/supported-formats.md, 3 times (step 59, certificate.json, rungs/R2.json):
- line 6: '//github.com/immich-app/immich/blob/main/server/src/utils/mime-types.ts' is the old path of server/src/utils/mime-types.ts (moved to server/src/shared/mime-types.ts) (step 59, certificate.json, rungs/R2.json)

Files: docs/docs/features/supported-formats.md

Source: certificate; steps 59; certificates certificate.json, rungs/R2.json

tool-config-added (2)

Inert tool config added (K1): server/.dependency-cruiser.json F-06567c18470b

K1 added a dependency-cruiser config at the package root that proves inert: no tsconfig program loads it, no reference references it, no published package packs it, and no other file names or globs it; CI path filters still trigger its jobs. (narration: Nemotron 3.5 Lightning)

Evidence
K1 reported one finding in server/.dependency-cruiser.json, 2 times (certificate.json, rungs/R4.json):
- added at the package root and proven inert: in no tsconfig program, loaded by no reference, packed by no published package, named or globbed by no other file, and the tool runs nowhere; CI path filters match it, so it triggers their jobs: 'server/**' in .github/workflows/docker.yml (line 45), 'serv… (certificate.json, rungs/R4.json)

Files: server/.dependency-cruiser.json

Source: certificate; certificates certificate.json, rungs/R4.json

Inert tool config added (K1): server/.dependency-cruiser-known-violations.json F-d75862632092

K1 added a dependency-cruiser-known-violations config at the package root that proves inert: no tsconfig program loads it, no reference references it, no published package packs it, and no other file names or globs it; CI path filters still trigger its jobs. (narration: Nemotron 3.5 Lightning)

Evidence
K1 reported one finding in server/.dependency-cruiser-known-violations.json, 2 times (certificate.json, rungs/R4.json):
- added at the package root and proven inert: in no tsconfig program, loaded by no reference, packed by no published package, named or globbed by no other file, and the tool runs nowhere; CI path filters match it, so it triggers their jobs: 'server/**' in .github/workflows/docker.yml (line 45), 'serv… (certificate.json, rungs/R4.json)

Files: server/.dependency-cruiser-known-violations.json

Source: certificate; certificates certificate.json, rungs/R4.json

coverage-scope (1)

Coverage globs match other files (K4): server/test/vitest.config.mjs F-800da5f4439a

K4 reported six distinct coverage-glob findings in the vitest config that match 122 steps across certificate.json and rung JSON files, where globs such as 'src/services/**' change matches when files move to module folders. (narration: Nemotron 3.5 Lightning)

Evidence
K4 reported 6 distinct findings in server/test/vitest.config.mjs, 122 times (steps 1–13, 15–39, 44–51, 54–57, 59, certificate.json, rungs/R1.json, rungs/R2.json):
- line 19: 'src/services/**' is the glob server/src/services/** whose matches change (2 moved files, e.g. server/src/services/activity.service.spec.ts -> server/src/modules/activity/activity.service.spec.ts) of server/src/services/activity.service.spec.ts (moved to server/src/modules/activity/activit… (steps 1–13, 15–38, 44, 50–51, 54–57, 59, certificate.json, rungs/R1.json, rungs/R2.json)
- line 21: 'src/services/*.spec.ts' is the glob server/src/services/*.spec.ts whose matches change (1 moved files, e.g. server/src/services/activity.service.spec.ts -> server/src/modules/activity/activity.service.spec.ts) of server/src/services/activity.service.spec.ts (moved to server/src/modules/ac… (steps 1–5, 7–12, 15–21, 23–37, 44, 50–51, 55, 57, 59, certificate.json, rungs/R1.json, rungs/R2.json)
- line 19: 'src/utils/**' is the glob server/src/utils/** whose matches change (1 moved files, e.g. server/src/utils/asset.util.ts -> server/src/modules/asset/asset.util.ts) of server/src/utils/asset.util.ts (moved to server/src/modules/asset/asset.util.ts) [config at test.coverage.include]; coverage… (steps 4, 7–8, 10, 15, 24, 29, 31, 34, 38–39, 44–51, 59, certificate.json, rungs/R1.json, rungs/R2.json)
- line 24: 'src/services/index.ts' is the old path of server/src/services/index.ts (moved to server/src/platform/registry/services/index.ts) [config at test.coverage.exclude]; coverage now measures a different file set (no coverage threshold in this file, so no gate changes) (step 54, certificate.json, rungs/R2.json)
- line 19: 'src/cores/**' is the glob server/src/cores/** whose matches change (2 moved files, e.g. server/src/cores/storage.core.spec.ts -> server/src/platform/storage/storage.core.spec.ts) of server/src/cores/storage.core.spec.ts (moved to server/src/platform/storage/storage.core.spec.ts) [config a… (step 55, certificate.json, rungs/R2.json)
- line 22: 'src/services/api.service.ts' is the old path of server/src/services/api.service.ts (moved to server/src/shared/api.service.ts) [config at test.coverage.exclude]; coverage now measures a different file set (no coverage threshold in this file, so no gate changes) (step 59, certificate.json, rungs/R2.json)

Files: server/test/vitest.config.mjs

Source: certificate; steps 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 44, 45, 46, 47, 48, 49, 50, 51, 54, 55, 56, 57, 59; certificates certificate.json, rungs/R1.json, rungs/R2.json

default-root-dir (1)

Emit without a rootDir (K7): e2e/tsconfig.json F-966da7d59056

The e2e tsconfig emits into e2e/dist without specifying a rootDir, so TypeScript uses its default of e2e for both the input and output, a situation recorded 67 times across steps and rung files. (narration: Nemotron 3.5 Lightning)

Evidence
K7 reported one finding in e2e/tsconfig.json, 67 times (steps 1–62, certificate.json, rungs/R1.json, rungs/R2.json, rungs/R3.json, rungs/R4.json):
- emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e (steps 1–62, certificate.json, rungs/R1.json, rungs/R2.json, rungs/R3.json, rungs/R4.json)

Files: e2e/tsconfig.json

Source: certificate; steps 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62; certificates certificate.json, rungs/R1.json, rungs/R2.json, rungs/R3.json, rungs/R4.json

opaque-dynamic-load (1)

A module loaded by a computed path (K4): server/src/repositories/database.repository.ts F-70d9e19108a1

Evidence
K4 reported one finding in server/src/repositories/database.repository.ts, 66 times (steps 1–62, certificate.json, rungs/R1.json, rungs/R2.json, rungs/R3.json):
- line 510: import(filePath) loads a module by a path K4 can't evaluate (steps 1–62, certificate.json, rungs/R1.json, rungs/R2.json, rungs/R3.json)

Files: server/src/repositories/database.repository.ts

Source: certificate; steps 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62; certificates certificate.json, rungs/R1.json, rungs/R2.json, rungs/R3.json

ungated-coverage-glob (1)

Coverage globs match other files, with no gate: server/test/vitest.config.mjs F-89500b32bdee

The vitest config contains six distinct coverage-glob findings that match 107 steps, but no threshold or check gates the coverage, so the globs match differently for moved service and utility files without enforcing any rule. (narration: Nemotron 3.5 Lightning)

Evidence
The run recorded 6 distinct findings in server/test/vitest.config.mjs, 107 times (steps 1–13, 15–39, 44–51, 54–57, 59):
- server/test/vitest.config.mjs line 19 [test.coverage.include]: coverage glob 'src/services/**' (server/src/services/**) matches differently for server/src/services/activity.service.ts (moving to server/src/modules/activity/activity.service.ts), server/src/services/activity.service.spec.ts (moving t… (steps 1–13, 15–38, 44, 50–51, 54–57, 59)
- server/test/vitest.config.mjs line 21 [test.coverage.exclude]: coverage glob 'src/services/*.spec.ts' (server/src/services/*.spec.ts) matches differently for server/src/services/activity.service.spec.ts (moving to server/src/modules/activity/activity.service.spec.ts); nothing in server/test/vitest.… (steps 1–5, 7–12, 15–21, 23–37, 44, 50–51, 55, 57, 59)
- server/test/vitest.config.mjs line 19 [test.coverage.include]: coverage glob 'src/utils/**' (server/src/utils/**) matches differently for server/src/utils/asset.util.ts (moving to server/src/modules/asset/asset.util.ts); nothing in server/test/vitest.config.mjs gates coverage (no threshold or check… (steps 4, 7–8, 10, 15, 24, 29, 31, 34, 38–39, 44–51, 59)
- server/test/vitest.config.mjs line 24 [test.coverage.exclude]: coverage glob 'src/services/index.ts' matches differently for server/src/services/index.ts (moving to server/src/platform/registry/services/index.ts); nothing in server/test/vitest.config.mjs gates coverage (no threshold or check-covera… (step 54)
- server/test/vitest.config.mjs line 19 [test.coverage.include]: coverage glob 'src/cores/**' (server/src/cores/**) matches differently for server/src/cores/storage.core.ts (moving to server/src/platform/storage/storage.core.ts), server/src/cores/storage.core.spec.ts (moving to server/src/platform/st… (step 55)
- server/test/vitest.config.mjs line 22 [test.coverage.exclude]: coverage glob 'src/services/api.service.ts' matches differently for server/src/services/api.service.ts (moving to server/src/shared/api.service.ts); nothing in server/test/vitest.config.mjs gates coverage (no threshold or check-coverage… (step 59)

Files: server/test/vitest.config.mjs

Source: run; steps 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 44, 45, 46, 47, 48, 49, 50, 51, 54, 55, 56, 57, 59

findings.json · findings.md · the PR body

Table access

63 table names × the 32 groups whose files touch them, from the planner's facts at the base commit (Kysely, Prisma and Drizzle call shapes), mapped through the plan's placements. 3 tables are written by files of several groups: asset (module/asset, module/duplicate, module/stack, module/trash); cluster_group (module/cluster-group, module/person); session_sync_checkpoint (module/session, module/sync). The findings log records 3 multi-writer-table findings, not fixed.

Table access by group
written by the groupread onlywritten, by one of several groups (⚠)
activityalbumalbum_assetalbum_userapi_keyagg⚠ assetasset_audioasset_editasset_exifasset_fileasset_job_statusasset_keyframeasset_metadataasset_videocitiescterestoday⚠ cluster_groupcluster_group_requestduplicatesintegrity_reportlibrarygeodata_placesnaturalearth_countriesmemorymemory_assetnotificationasset_ocrocr_searchpartnerasset_faceface_searchmappingpersonperson_groupperson_usersharedpluginplugin_methodsmart_searchsession⚠ session_sync_checkpointshared_linkshared_link_assetstacksystem_metadatacreated_tagdescendantstagtag_assettag_closureuseruser_metadataversion_historyvideo_stream_segmentvideo_stream_sessionvideo_stream_variantworkflowworkflow_logworkflow_stepmove_historymodule/activitymodule/albummodule/api-keymodule/assetmodule/cluster-groupmodule/downloadmodule/duplicatemodule/integritymodule/librarymodule/mapmodule/memorymodule/notificationmodule/ocrmodule/partnermodule/personmodule/pluginmodule/searchmodule/sessionmodule/shared-linkmodule/stackmodule/syncmodule/system-metadatamodule/tagmodule/trashmodule/usermodule/versionmodule/video-streammodule/viewmodule/workflowplatform/accessplatform/databaseplatform/move

Rows are tables, ordered under the first group that writes them; columns are groups in plan order. The facts read table names from query call shapes. Under planner rules 1 (immich's recorded plan) a common table expression's alias (.with('cte', …)) shows up as a read-only table; rules 2 (S8) leave out an alias read inside the query that declares it.

Table view
TableWritten byRead only by
activitymodule/activityplatform/access
albummodule/albummodule/shared-link module/sync platform/access platform/database
album_assetmodule/albummodule/asset module/download module/map module/shared-link module/sync platform/access platform/database
album_usermodule/albummodule/shared-link module/sync platform/access platform/database
api_keymodule/api-key–
agg–module/asset
⚠ assetmodule/asset module/duplicate module/stack module/trashmodule/activity module/album module/download module/integrity module/library module/map module/memory module/person module/search module/shared-link module/sync module/user module/video-stream module/view module/workflow platform/access platform/database platform/move
asset_audiomodule/assetmodule/video-stream
asset_editmodule/assetplatform/database
asset_exifmodule/assetmodule/album module/download module/duplicate module/library module/map module/person module/search module/shared-link module/stack module/sync module/user module/video-stream module/workflow platform/database
asset_filemodule/assetmodule/integrity module/memory platform/access platform/database
asset_job_statusmodule/assetmodule/person
asset_keyframemodule/assetmodule/video-stream
asset_metadatamodule/asset–
asset_videomodule/assetmodule/video-stream
cities–module/asset
cte–module/asset module/duplicate module/search
res–module/asset
today–module/asset
⚠ cluster_groupmodule/cluster-group module/person–
cluster_group_requestmodule/cluster-groupplatform/access
duplicates–module/duplicate
integrity_reportmodule/integrity–
librarymodule/libraryplatform/database
geodata_placesmodule/mapmodule/search
naturalearth_countriesmodule/map–
memorymodule/memorymodule/sync platform/access
memory_assetmodule/memory–
notificationmodule/notificationplatform/access
asset_ocrmodule/ocr–
ocr_searchmodule/ocrplatform/database
partnermodule/partnermodule/sync platform/access
asset_facemodule/personmodule/memory module/search platform/access platform/database
face_searchmodule/personmodule/search
mapping–module/person
personmodule/personmodule/integrity module/memory module/search platform/access platform/database
person_groupmodule/person–
person_usermodule/personplatform/access
shared–module/person
pluginmodule/pluginmodule/workflow
plugin_methodmodule/pluginmodule/workflow
smart_searchmodule/searchmodule/asset module/duplicate platform/database
sessionmodule/sessionplatform/access
⚠ session_sync_checkpointmodule/session module/sync–
shared_linkmodule/shared-linkmodule/album platform/access
shared_link_assetmodule/shared-linkplatform/access
stackmodule/stackmodule/asset platform/access
system_metadatamodule/system-metadata–
created_tag–module/tag
descendants–module/tag
tagmodule/tagmodule/asset module/duplicate module/stack platform/access platform/database
tag_assetmodule/tagmodule/asset module/duplicate module/stack platform/database
tag_closuremodule/tagplatform/database
usermodule/usermodule/activity module/album module/api-key module/asset module/cluster-group module/partner module/person module/search module/session module/shared-link module/sync platform/access platform/database
user_metadatamodule/user–
version_historymodule/version–
video_stream_segmentmodule/video-stream–
video_stream_sessionmodule/video-stream–
video_stream_variantmodule/video-stream–
workflowmodule/workflowplatform/access
workflow_logmodule/workflow–
workflow_stepmodule/workflow–
move_historyplatform/move–

Cost

This run: the plan cost $0.1998 when it was recorded; planner spend during the run $0.0000 (budget run s6, mode auto); the findings narration $0.0010 in 2 calls of Nemotron 3.5 Lightning (thinking off) (replayed, $0 now). Replaying the plan and the narration from the committed cassettes costs $0.

The whole project's spend on Nebius Token Factory, from the gateway's ledger (budget/ledger.jsonl): $24.3980 of the $50.00 hard cap. The lines marked reconciled bring the ledger to the Nebius console bill: what Token Factory billed differently from the gateway's count (a lost call, cached input at its cached price, calls it didn't bill). The G3 runs (opencode with Nemotron 3 Super and, in S9, with Ultra: the generic-agent baseline) account for $8.9572 of it. The runs tf-probes, g1, g3-smoke, g3-immich, g3-mcphub, g3u-smoke, g3u-immich, g3u-immich-persistent are carried over from the gate spike as one line each.

LLM spend by budget run
tf-probes$0.0250g1$1.7552g3-smoke$0.0143g3-immich$4.9333g3-mcphub$0.8603s5$1.2877 of $3.00s6$0.4343 of $3.00s7$1.1213 of $5.00s8$0.1114 of $3.00s8b$3.7268 of $7.00s8c$0.5941 of $3.00s8d$6.3850 of $10.00g3u-smoke$0.0570g3u-immich$0.5456g3u-immich-persistent$2.5468
Table view
Budget runPaid callsCostCapModelsNotes
tf-probes82$0.0250––carried over from spike/gates:spike/llm/ledger.jsonl: 82 paid calls, $0.0250
g153$1.7552––carried over from spike/gates:spike/llm/ledger.jsonl: 53 paid calls, $1.7042 reconciled, $0.0510: Nebius console 2026-10-14 21:31 UTC ($9.31) vs ledger ($9.259): Super output +58k and input +8k tokens are one G1 call lost to 'fetch failed' at 2026-10-02T13:46:58Z (estimate $0.0601), which the spike gateway booked at $0 and Token Factory billed
g3-smoke6$0.0143––carried over from spike/gates:spike/llm/ledger.jsonl: 6 paid calls, $0.0143
g3-immich251$4.9333––carried over from spike/gates:spike/llm/ledger.jsonl: 251 paid calls, $4.9333
g3-mcphub62$0.8603––carried over from spike/gates:spike/llm/ledger.jsonl: 62 paid calls, $0.8603
s517$1.2877$3.00Nemotron 3 Ultra
s638$0.4343$3.00Nemotron 3 Ultra, Nemotron 3.5 Lightning
s712$1.1213$5.00Nemotron 3 Ultra
s83$0.1114$3.00Nemotron 3 Ultra
s8b70$3.7268$7.00Nemotron 3 Ultra, Nemotron 3.5 Super VLreconciled, −$0.2723: Nebius console export, 2026-09-24 to 10-24 (corupta, 2026-10-24): $24.40 billed; Ultra's cached input billed at its cached price, $0.12/M (from 2026-10-20 20:01 UTC at the latest; S7's hits on 2026-10-17 were billed in full), which the ledger charged at $1.00/M: 252,416 tokens; Super VL's cached input at $0.06/M, which the ledger charged at $0.30/M: 208,896 tokens reconciled, $0.0000: Nebius console export, 2026-09-24 to 10-24 (corupta, 2026-10-24): $24.40 billed; the Super VL call stopped at 2026-10-20T20:54Z leaves no trace in the bill (Super VL's billed input, 0.57M, is the 200 responses' 565,968 uncached prompt tokens; billed without a cache hit, its ~11k-token prompt would have made it 0.58M; sub-cent either way): its $0.0387 reservation settles at $0
s8c3$0.5941$3.00Nemotron 3.5 Super VLreconciled, −$0.7033: Nebius console export, 2026-09-24 to 10-24 (corupta, 2026-10-24): $24.40 billed; Super VL's cached input at $0.06/M, which the ledger charged at $0.30/M: 6,528 tokens; the non-streamed call cut at 600 s (HTTP 504, 2026-10-21T00:31Z), booked at its $0.7017 estimate, was not billed (Super VL's billed output, 9.09M, matches its 200 responses' 9,092,987 tokens to the console's 0.01M)
s8d30$6.3850$10.00Nemotron 3.5 Super VLreconciled, −$0.0345: Nebius console export, 2026-09-24 to 10-24 (corupta, 2026-10-24): $24.40 billed; Super VL's cached input at $0.06/M, which the ledger charged at $0.30/M: 143,616 tokens
g3u-smoke7$0.0570––carried over from spike/g3-ultra:spike/llm/ledger.jsonl: 7 paid calls, $0.0762 reconciled, −$0.0191: Nebius console export, 2026-09-24 to 10-24 (corupta, 2026-10-24): $24.40 billed; Ultra's cached input billed at its cached price, $0.12/M (from 2026-10-20 20:01 UTC at the latest; S7's hits on 2026-10-17 were billed in full), which the ledger charged at $1.00/M: 21,760 tokens
g3u-immich49$0.5456––carried over from spike/g3-ultra:spike/llm/ledger.jsonl: 49 paid calls, $1.8630 reconciled, −$1.3174: Nebius console export, 2026-09-24 to 10-24 (corupta, 2026-10-24): $24.40 billed; Ultra's cached input billed at its cached price, $0.12/M (from 2026-10-20 20:01 UTC at the latest; S7's hits on 2026-10-17 were billed in full), which the ledger charged at $1.00/M: 1,497,088 tokens
g3u-immich-persistent170$2.5468––carried over from spike/g3-ultra:spike/llm/ledger.jsonl: 170 paid calls, $11.7612 reconciled, −$9.2144: Nebius console export, 2026-09-24 to 10-24 (corupta, 2026-10-24): $24.40 billed; Ultra's cached input billed at its cached price, $0.12/M (from 2026-10-20 20:01 UTC at the latest; S7's hits on 2026-10-17 were billed in full), which the ledger charged at $1.00/M: 10,470,912 tokens
total853$24.3980$50.00

A/B: the same task, a generic agent

G3 gave opencode 1.18.34 with NVIDIA Nemotron 3 Super on Nebius Token Factory the same restructure, with a fixed prompt and no human input. Its branches were certified in session S4 by our checker, the version before this run's (certificate format 1; K7 came later). The same agent on Nemotron 3 Ultra, the model ac plans with (S9), is on the site's A/B page: its single-shot changed nothing, and its persistent run hit its $12 cap in turn 1 with every import of the moved files dangling.

immich server/ @ 02063972e8

Target: immich @ 02063972e8. Base: tsc 0 errors; vitest 105 test files, 2,337 cases (docs/gates.md, G2); the OpenAPI spec is 947,932 bytes (the certificates' K8).

A green test count is not proof. On immich, the branch g3/opencode-super (opencode + Nemotron 3 Super, single-shot) still passes all 2,337 of the base's test cases, while 66 of its 171 test files fail to load and tsc reports 1,680 errors (its certificate: K6, K8).

ac, the full ladder (ours)ac, one R1-style step (ours)opencode + Nemotron 3 Super, single-shotopencode + Nemotron 3 Super, persistentSource
Whoac architecture-cleaner: Nemotron 3 Ultra plans, the executor moves, the certifier checks every commitac architecture-cleaner's executor, one move of 292 of the 302 controllers, services, repositories and DTOs (the 3 index.ts barrels and the barrel's spec, two process.cwd() specs, the three import.meta.dirname users and services/shared/user-methods.ts stay)opencode 1.18.34, NVIDIA Nemotron 3 Super on Nebius Token Factory, one `opencode run` with the fixed promptthe same agent; whenever it stopped, an automated reply reported typecheck and test results and asked it to continue
Branchac/s6-ladder (S6)
run report
ac/s3-r1 (S3)g3/opencode-super (G3 (S2))g3/opencode-super-persistent (G3 (S2))
OutcomeCompleted unattended: 63 commits, each certified on its first attempt; every rung and the whole PR PASS with the oraclesOne certified commitStopped after 169 s and asked the user to run its sed commandsStopped by the $5 budget cap during turn 5, after 33 mindocs/sessions/s6.md; docs/sessions/s3.md; docs/gates.md (G3 table)
What the diff is367 files moved into 38 modules, 20 platform folders and shared/; 2,474 specifier edits in 515 files; 2 boundary-rule files added and proven inert; every other byte identical
certificate K1: 367 moved, 180 edited in place, 2 added (2 inert tool configs), 0 deleted
292 files moved into 100 modules; 1,445 specifier edits in 386 files; every other byte identical
certificate K1: 292 moved, 152 edited in place, 0 added, 0 deleted
211 files copied into src/features/, originals kept; every rewritten import corrupted
certificate K1: 0 moved, 0 edited in place, 211 added (31 of them copies of files that still exist), 0 deleted
297 moved, 562 TypeScript files copied (a src.backup/ tree), 68 edited, 12 Python scripts left behind
certificate K1: 365 moved, 0 edited in place, 614 added (291 of them copies of files that still exist), 0 deleted
docs/storyboard.md (lead table); docs/gates.md (G3 table); runs/immich-ladder/certificate.txt (K1, K2)
certificate line: each arm's certificate, K1
tsc errors (base: 0)0
certificate K8: tsc exit 0
0
certificate K8: tsc exit 0
1,680
certificate K8: tsc exited 1 on head (1,680 diagnostics), 0 on base
768 (nest build: 4,675)
certificate K8: tsc exited 1 on head (768 diagnostics), 0 on base
docs/storyboard.md (lead table); docs/gates.md (G3 table); runs/immich-ladder/certificate.txt (K8)
certificate line: each arm's certificate, K8 tsc
Unit suite (base: 105 files, 2,337 cases)105/105 files, 2,337/2,337 cases
certificate K8: unit 105/105 files and 2,337/2,337 cases equal to base (head: 105/105 files load, 2,337 passed, 0 failed, 0 skipped)
105/105 files, 2,337/2,337 cases
certificate K8: unit 105/105 files and 2,337/2,337 cases equal to base (head: 105/105 files load, 2,337 passed, 0 failed, 0 skipped)
2,337/2,337 cases pass, but 66 of 171 spec files never load
certificate K8: unit 105/171 files and 2,337/2,337 cases equal to base (head: 105/171 files load, 2,337 passed, 0 failed, 0 skipped)
5/105 files, 52 cases
certificate K8: unit 5/105 files and 52/2,337 cases equal to base (head: 5/105 files load, 52 passed, 0 failed, 0 skipped)
docs/storyboard.md (lead table); runs/immich-ladder/certificate.txt (K6, K8)
certificate line: each arm's certificate, K8 unit
OpenAPI spec (base: 947,932 bytes)byte-identical
certificate K8: openapi byte-identical to the base's open-api/immich-openapi-specs.json (947,932 bytes)
byte-identical
certificate K8: openapi byte-identical to the base's open-api/immich-openapi-specs.json (947,932 bytes)
byte-identical: the copies are dead code
certificate K8: openapi byte-identical to the base's open-api/immich-openapi-specs.json (947,932 bytes), but 1 step failed on head
not produced: sync-open-api crashes
certificate K8: openapi produced nothing
docs/storyboard.md (lead table); docs/gates.md (G3 table); runs/immich-ladder/certificate.txt (K8)
certificate line: each arm's certificate, K8 openapi
Non-specifier lines changed in moved or copied files0 (K2)
certificate K2: 2474 specifier spans changed in 515 files; every other byte identical
0 (K2)
certificate K2: 1445 specifier spans changed in 386 files; every other byte identical
1,104 (2.4%)
certificate K2: no file paired with a base file changed, so there was nothing to compare; K1 counts the 211 added files
0, plus 926 in modified files
certificate K2: no file paired with a base file changed, so there was nothing to compare; K1 counts the 614 added files
G3 arms: docs/gates.md (G3 table, the gate's line diff); ac arms: the certificates' K2
certificate line: each arm's certificate, K2
New dangling specifiers0 (K3a, K3b, K3c: every site resolves to its base target)
certificate K3b: vitest 4.1.11: 4837 sites in 672 files resolve to map(base)
0 (K3a, K3b, K3c)
certificate K3b: vitest 4.1.11: 4837 sites in 672 files resolve to map(base)
0: its 552 rewritten imports are syntax errors, not specifiers, so the analyzer counts none; the rest still import the originals
certificate K3b: vitest 4.1.11: 4837 sites in 672 files resolve to map(base)
2,923
certificate K3b: vitest 4.1.11: 4548 violations (2802 dangling, 131 retargeted, 1615 dangling in added files)
G3 arms: docs/gates.md (G3 table, the gate's TypeScript analyzer); ac arms: the certificates' K3a–K3c
certificate line: each arm's certificate, K3b
Behavior changes no unit test catchesNone found: K4 finds no moved file whose location reaches behavior; 12 logged stack traces now name the new path (K4 findings)
certificate K4: 367 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (13 findings in docs, comments or ungated coverage settings)
None found (K4; 11 logged stack traces now name the new path)
certificate K4: 292 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (9 findings in docs, comments or ungated coverage settings)
0 claims survived review: the copies are dead code
certificate K4: 0 path-exposing uses in moved files (and 3 in added files), 0 computed paths into changed directories, 0 old paths in code/config (0 in coverage settings)
2 survived review: database.repository.ts and config.repository.ts moved but kept their import.meta.dirname paths (migrations, helmet.json)
certificate K4: 12 path-exposing uses in moved files (and 15 in added files), 2 computed paths into changed directories, 52 old paths in code/config (0 in coverage settings)
G3 arms: docs/gates.md (Addendum: G3 review); ac arms: the certificates' K4
certificate line: each arm's certificate, K4
LLM cost$0.1998 for the plan when recorded (Nemotron 3 Ultra) and $0.0010 for the findings narration (Nemotron 3.5 Lightning); a replay costs $0$0$0.30 (0.98M input tokens, 51 calls)$4.63 (15.3M input tokens, 200 calls)runs/immich-ladder/run.json (cost); docs/sessions/s6.md; docs/storyboard.md (lead table); docs/gates.md (G3 table)
Time1 h 55 m wall time on a quiet machine, certificates includedexecutor 14 s; certificate: static checks 124 s, oracles 111 s169 s33 mindocs/sessions/s6.md; docs/storyboard.md (lead table)
ac certify verdictPASS (with oracles)PASS (with oracles)FAIL (with oracles)
failing: K1, K3a, K4, K6, K8
FAIL (with oracles)
failing: K1, K3a, K3b, K3c, K4, K6, K8
the certificate files; one row per check below
K0 EnvelopePASSPASSPASSPASS
K1 Move-set integrityPASSPASSFAILFAIL
K2 Byte-span confinementPASSPASSPASS
nothing to compare: K1 counts the 211 added files
PASS
nothing to compare: K1 counts the 614 added files
K3a Resolution identity under TypeScriptPASSPASSFAILFAIL
K3b Resolution identity under the test runnerPASSPASSPASSFAIL
K3c Resolution identity under the runtimePASSPASSPASSFAIL
K4 Location scanPASSPASSFAILFAIL
K6 Test inventoryPASSPASSFAILFAIL
K7 Emit layoutPASSnot checked: K7 came after this certificate (S6)not checked: K7 came after this certificate (S6)not checked: K7 came after this certificate (S6)
K8 Oracles on the commitPASSPASSFAILFAIL

Where the gate's numbers and the certificates' differ

The single-shot branch's restructure is a dead copy tree: nothing imports its 211 copies, so the tests still run against the original files. (docs/gates.md (G3 table; Addendum: G3 review))

The persistent run is the reference baseline, because single-shot runs quit within 3 minutes. (docs/gates.md (Plan corrections, item 3))

The certificates

ac, the full ladder: PASS sha256:9a5b2404631c…

certificate JSON

ac certify 02063972e8..c4be040b57 (package root server/), profile immich
trees: 424df72c34..4e457bb4e8
pathMap: 367 moves, 180 edited in place, 2917 unchanged, 2 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 367 moved files (0.2 s)
PASS  K1  Move-set integrity: 367 moves, 180 files edited in place, 2 inert tool configs added, nothing else added or deleted (8.3 s)
        finding (tool-config-added) server/.dependency-cruiser-known-violations.json: added at the package root and proven inert: in no tsconfig program, loaded by no reference, packed by no published package, named or globbed by no other file, and the tool runs nowhere; CI path filters match it, so it triggers their jobs: 'server/**' in .github/workflows/docker.yml (line 45), 'server/**' in .github/workflows/test.yml (line 46)
        finding (tool-config-added) server/.dependency-cruiser.json: added at the package root and proven inert: in no tsconfig program, loaded by no reference, packed by no published package, named or globbed by no other file, and the tool runs nowhere; CI path filters match it, so it triggers their jobs: 'server/**' in .github/workflows/docker.yml (line 45), 'server/**' in .github/workflows/test.yml (line 46)
PASS  K2  Byte-span confinement: 2474 specifier spans changed in 515 files; every other byte identical (3.4 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 2474 rewritten specifiers keep their form (1.8 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (5.1 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (6.7 s)
PASS  K4  Location scan: 367 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (13 findings in docs, comments or ungated coverage settings) (5.7 s)
        finding (stack-text) server/src/repositories/metadata.repository.ts: moved to server/src/platform/metadata/metadata.repository.ts; 1 stack-trace reads passed along as text (line 133); their frames now name the new path
        finding (stack-text) server/src/repositories/websocket.repository.ts: moved to server/src/platform/websocket/websocket.repository.ts; 1 stack-trace reads passed along as text (line 95); their frames now name the new path
        finding (stack-text) server/src/services/asset-media.service.ts: moved to server/src/modules/asset/asset-media.service.ts; 1 stack-trace reads passed along as text (line 224); their frames now name the new path
        … 23 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (0.0 s)
PASS  K7  Emit layout: 7 emitting programs keep their outDir and rootDir (1 by TypeScript's default) (0.5 s)
        finding (default-root-dir) e2e/tsconfig.json: emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e
PASS  K8  Oracles on the commit: tsc exit 0; unit 105/105 files and 2,337/2,337 cases equal to base (head: 105/105 files load, 2,337 passed, 0 failed, 0 skipped); openapi byte-identical to the base's open-api/immich-openapi-specs.json (947,932 bytes) (114.9 s)

verdict: PASS (static checks and oracles)
digest: sha256:9a5b2404631c2ac668462ad93fcbcd116637244e2b4f76e987bcc4e23e8be2b5
ac, one R1-style step: PASS sha256:2e9e00c96572…

certificate JSON

ac certify 02063972e8..ff429b0d24 (package root server/)
pathMap: 292 moves, 152 edited in place, 3020 unchanged, 0 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 292 moved files (8.5 s)
PASS  K1  Move-set integrity: 292 moves, 152 files edited in place, nothing added or deleted (1.5 s)
PASS  K2  Byte-span confinement: 1445 specifier spans changed in 386 files; every other byte identical (2.9 s)
PASS  K3a Resolution identity under TypeScript: 6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 1445 rewritten specifiers keep their form (1.5 s)
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (5.8 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (7.2 s)
PASS  K4  Location scan: 292 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (9 findings in docs, comments or ungated coverage settings) (5.5 s)
        finding (stack-text) server/src/repositories/metadata.repository.ts: moved to server/src/modules/metadata/metadata.repository.ts; 1 stack-trace reads passed along as text (line 133); their frames now name the new path
        finding (stack-text) server/src/repositories/websocket.repository.ts: moved to server/src/modules/websocket/websocket.repository.ts; 1 stack-trace reads passed along as text (line 95); their frames now name the new path
        finding (stack-text) server/src/services/asset-media.service.ts: moved to server/src/modules/asset-media/asset-media.service.ts; 1 stack-trace reads passed along as text (line 224); their frames now name the new path
        … 18 more findings
PASS  K6  Test inventory: vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal (91.2 s)
PASS  K8  Oracles on the commit: tsc exit 0; unit 105/105 files and 2,337/2,337 cases equal to base (head: 105/105 files load, 2,337 passed, 0 failed, 0 skipped); openapi byte-identical to the base's open-api/immich-openapi-specs.json (947,932 bytes) (110.7 s)

verdict: PASS (static checks and oracles)
digest: sha256:2e9e00c96572e7347cf00084cacd7e371c3004c261092888575bb32d99138820

Ac-Certificate: pass (full) K0=pass K1=pass K2=pass K3=pass K4=pass K6=pass K8=pass
Ac-Certificate-Base: 02063972e82b1bfd17b6fc2e3b3ff39936229ea5
Ac-Certificate-Digest: sha256:2e9e00c96572e7347cf00084cacd7e371c3004c261092888575bb32d99138820
opencode + Nemotron 3 Super, single-shot: FAIL sha256:8cbe6c92987f…

certificate JSON

ac certify 02063972e8..03e76f3faa (package root server/)
pathMap: 0 moves, 0 edited in place, 3464 unchanged, 211 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 889 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 0 moved files (9.1 s)
FAIL  K1  Move-set integrity: 211 violations (211 added, 0 deleted, 31 copies) (1.2 s)
        server/src/features/activity/activity.controller.spec.ts: added: no file in base has its content (modulo specifiers)
        server/src/features/activity/activity.controller.ts: added: no file in base has its content (modulo specifiers)
        server/src/features/activity/activity.dto.ts: added: no file in base has its content (modulo specifiers)
        server/src/features/activity/activity.repository.ts: added: a copy of server/src/repositories/activity.repository.ts, which still exists
        server/src/features/activity/activity.service.spec.ts: added: no file in base has its content (modulo specifiers)
        server/src/features/activity/activity.service.ts: added: no file in base has its content (modulo specifiers)
        server/src/features/album/album.controller.spec.ts: added: no file in base has its content (modulo specifiers)
        server/src/features/album/album.controller.ts: added: no file in base has its content (modulo specifiers)
        … 203 more
PASS  K2  Byte-span confinement: 0 specifier spans changed in 0 files; every other byte identical (0.0 s)
FAIL  K3a Resolution identity under TypeScript: 211 violations (211 added source files) (1.3 s)
        server/src/features/activity/activity.controller.spec.ts: added: its 3 reference sites have no counterpart in base
        server/src/features/activity/activity.controller.ts: added: its 7 reference sites have no counterpart in base
        server/src/features/activity/activity.dto.ts: added: its 4 reference sites have no counterpart in base
        server/src/features/activity/activity.repository.ts: added: its 10 reference sites have no counterpart in base
        server/src/features/activity/activity.service.spec.ts: added: its 6 reference sites have no counterpart in base
        server/src/features/activity/activity.service.ts: added: its 3 reference sites have no counterpart in base
        server/src/features/album/album.controller.spec.ts: added: its 3 reference sites have no counterpart in base
        server/src/features/album/album.controller.ts: added: its 6 reference sites have no counterpart in base
        … 203 more
PASS  K3b Resolution identity under the test runner: vitest 4.1.11: 4837 sites in 672 files resolve to map(base) (6.6 s)
PASS  K3c Resolution identity under the runtime: 6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build) (7.6 s)
        finding (added-file-unresolved) server/src/features/plugin/plugin.dto.ts: nest-cli/emit: import '@immich/plugin-sdk' doesn't resolve (ERR_MODULE_NOT_FOUND) in a file with no base counterpart
        finding (added-file-unresolved) server/src/features/workflow/workflow.controller.spec.ts: nest-cli/emit: import '@immich/plugin-sdk' doesn't resolve (ERR_MODULE_NOT_FOUND) in a file with no base counterpart
        finding (added-file-unresolved) server/src/features/workflow/workflow.service.ts: nest-cli/emit: import '@immich/plugin-sdk' doesn't resolve (ERR_MODULE_NOT_FOUND) in a file with no base counterpart
FAIL  K4  Location scan: 0 path-exposing uses in moved files (and 3 in added files), 0 computed paths into changed directories, 0 old paths in code/config (0 in coverage settings) (0.9 s)
        server/src/features/library/library.service.spec.ts: added with no base counterpart; line 888: process.cwd()
        server/src/features/library/library.service.spec.ts: added with no base counterpart; line 1284: process.cwd()
        server/src/features/library/library.service.spec.ts: added with no base counterpart; line 1298: process.cwd()
        finding (stack-text) server/src/features/asset-media/asset-media.service.ts: added with no base counterpart; 1 stack-trace reads passed along as text (line 224); their frames now name the new path
        finding (stack-text) server/src/features/auth/auth.service.ts: added with no base counterpart; 1 stack-trace reads passed along as text (line 403); their frames now name the new path
        finding (stack-text) server/src/features/duplicate/duplicate.service.ts: added with no base counterpart; 1 stack-trace reads passed along as text (line 104); their frames now name the new path
        … 2 more findings
FAIL  K6  Test inventory: vitest 4.1.11: 66 violations (66 of 171 test files fail to load (base: 0), 66 new test files) (94.6 s)
        server/src/features/activity/activity.controller.spec.ts: new in the vitest test list (added in head; fails to load: x Unexpected token `[`. Expected a string literal ,-[/tmp/ac-s4-certify/g3-immich-opencode-super.full/worktree-head/server/src/features/activity/activity.controller.spec.ts:2:1] 1 | import request fro)
        server/src/features/activity/activity.service.spec.ts: new in the vitest test list (added in head; fails to load: x Unexpected token `[`. Expected a string literal ,-[/tmp/ac-s4-certify/g3-immich-opencode-super.full/worktree-head/server/src/features/activity/activity.service.spec.ts:2:1] 1 | import { BadRequestEx)
        server/src/features/album/album.controller.spec.ts: new in the vitest test list (added in head; fails to load: x Unexpected token `[`. Expected a string literal ,-[/tmp/ac-s4-certify/g3-immich-opencode-super.full/worktree-head/server/src/features/album/album.controller.spec.ts:2:1] 1 | import request from 'sup)
        server/src/features/album/album.service.spec.ts: new in the vitest test list (added in head; fails to load: x Unexpected token `[`. Expected a string literal ,-[/tmp/ac-s4-certify/g3-immich-opencode-super.full/worktree-head/server/src/features/album/album.service.spec.ts:2:1] 1 | import { BadRequestExceptio)
        server/src/features/app/app.controller.spec.ts: new in the vitest test list (added in head; fails to load: x Unexpected token `[`. Expected a string literal ,-[/tmp/ac-s4-certify/g3-immich-opencode-super.full/worktree-head/server/src/features/app/app.controller.spec.ts:2:1] 1 | import request from 'superte)
        server/src/features/asset/asset.controller.spec.ts: new in the vitest test list (added in head; fails to load: x Unexpected token `[`. Expected a string literal ,-[/tmp/ac-s4-certify/g3-immich-opencode-super.full/worktree-head/server/src/features/asset/asset.controller.spec.ts:2:1] 1 | import request from 'sup)
        server/src/features/asset/asset.service.spec.ts: new in the vitest test list (added in head; fails to load: x Unexpected token `[`. Expected a string literal ,-[/tmp/ac-s4-certify/g3-immich-opencode-super.full/worktree-head/server/src/features/asset/asset.service.spec.ts:3:1] 1 | import { BadRequestExceptio)
        server/src/features/asset-media/asset-media.controller.spec.ts: new in the vitest test list (added in head; fails to load: x Unexpected token `[`. Expected a string literal ,-[/tmp/ac-s4-certify/g3-immich-opencode-super.full/worktree-head/server/src/features/asset-media/asset-media.controller.spec.ts:2:1] 1 | import reque)
        … 58 more
FAIL  K8  Oracles on the commit: tsc exited 1 on head (1,680 diagnostics), 0 on base; unit 105/171 files and 2,337/2,337 cases equal to base (head: 105/171 files load, 2,337 passed, 0 failed, 0 skipped); openapi byte-identical to the base's open-api/immich-openapi-specs.json (947,932 bytes), but 1 step failed on head (118.9 s)
        tsc: `node_modules/.bin/tsc --noEmit --incremental false --pretty false` exited 1 on head (1,680 diagnostics), exit 0 on base (log /tmp/ac-s4-certify/g3-immich-opencode-super.full/oracles/head/tsc/step-1.log)
        server/src/features/activity/activity.controller.spec.ts: tsc: TS1005 ',' expected.
        server/src/features/activity/activity.controller.spec.ts: tsc: TS1002 Unterminated string literal.
        server/src/features/activity/activity.controller.spec.ts: tsc: TS1005 ',' expected.
        server/src/features/activity/activity.controller.spec.ts: tsc: TS1005 ',' expected.
        server/src/features/activity/activity.controller.spec.ts: tsc: TS1002 Unterminated string literal.
        server/src/features/activity/activity.controller.spec.ts: tsc: TS1005 ',' expected.
        server/src/features/activity/activity.controller.ts: tsc: TS1005 ',' expected.
        … 72 more

verdict: FAIL (static checks and oracles)
digest: sha256:8cbe6c92987fbc9132d2af720c36a32a3e5f5598021c85169e7d39de6b6d2beb

Ac-Certificate: fail (full) K0=pass K1=fail K2=pass K3=fail K4=fail K6=fail K8=fail
Ac-Certificate-Base: 02063972e82b1bfd17b6fc2e3b3ff39936229ea5
Ac-Certificate-Digest: sha256:8cbe6c92987fbc9132d2af720c36a32a3e5f5598021c85169e7d39de6b6d2beb
opencode + Nemotron 3 Super, persistent: FAIL sha256:90d2d44bbd64…

certificate JSON

ac certify 02063972e8..1da2348b7c (package root server/)
pathMap: 365 moves, 0 edited in place, 3099 unchanged, 614 added, 0 deleted

PASS  K0  Envelope: inside the envelope: 1242 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 365 moved files (23.1 s)
FAIL  K1  Move-set integrity: 979 violations (614 added, 0 deleted, 291 copies) (1.2 s)
        server/fix_app_files.py: added: no file in base has its content (modulo specifiers)
        server/fix_features_only.py: added: no file in base has its content (modulo specifiers)
        server/fix_indexes.py: added: no file in base has its content (modulo specifiers)
        server/fix_quotes.py: added: no file in base has its content (modulo specifiers)
        server/fix_quotes2.py: added: no file in base has its content (modulo specifiers)
        server/fix_restructure.py: added: no file in base has its content (modulo specifiers)
        server/rebuild_indexes.py: added: no file in base has its content (modulo specifiers)
        server/regenerate_indexes.py: added: no file in base has its content (modulo specifiers)
        … 971 more
        finding (ambiguous-match) 30 groups of identical files were paired by where their directories' other files went, then by name and path similarity
PASS  K2  Byte-span confinement: 0 specifier spans changed in 0 files; every other byte identical (4.2 s)
FAIL  K3a Resolution identity under TypeScript: 3097 violations (2168 resolution mismatches, 365 program or format changes, 564 added source files) (2.6 s)
        server/src/app.common.ts: line 9: import 'src/maintenance/maintenance-worker.service.js': expected file server/src.backup/maintenance/maintenance-worker.service.ts (typescript), got file server/src/maintenance/maintenance-worker.service.ts (typescript) under server/tsconfig.build.json, server/tsconfig.json
        server/src/app.common.ts: line 10: import 'src/middleware/websocket.adapter.js': expected file server/src.backup/middleware/websocket.adapter.ts (typescript), got file server/src/middleware/websocket.adapter.ts (typescript) under server/tsconfig.build.json, server/tsconfig.json
        server/src/app.common.ts: line 11: import 'src/repositories/config.repository.js': expected file server/src.backup/repositories/config.repository.ts (typescript), got unresolved under server/tsconfig.build.json, server/tsconfig.json
        server/src/app.common.ts: line 12: import 'src/repositories/logging.repository.js': expected file server/src.backup/repositories/logging.repository.ts (typescript), got unresolved under server/tsconfig.build.json, server/tsconfig.json
        server/src/app.common.ts: line 13: import 'src/repositories/telemetry.repository.js': expected file server/src.backup/repositories/telemetry.repository.ts (typescript), got unresolved under server/tsconfig.build.json, server/tsconfig.json
        server/src/app.common.ts: line 14: import 'src/services/api.service.js': expected file server/src.backup/services/api.service.ts (typescript), got unresolved under server/tsconfig.build.json, server/tsconfig.json
        server/src/app.common.ts: line 15: import 'src/utils/misc.js': expected file server/src.backup/utils/misc.ts (typescript), got file server/src/utils/misc.ts (typescript) under server/tsconfig.build.json, server/tsconfig.json
        server/src/app.module.ts: line 11: import 'src/controllers/index.js': expected file server/src.backup/controllers/index.ts (typescript), got file server/src/controllers/index.ts (typescript) under server/tsconfig.build.json, server/tsconfig.json
        … 3089 more
FAIL  K3b Resolution identity under the test runner: vitest 4.1.11: 4548 violations (2802 dangling, 131 retargeted, 1615 dangling in added files) (7.5 s)
        server/src/app.common.ts: site 8 'src/maintenance/maintenance-worker.service.js' (import): base server/src.backup/maintenance/maintenance-worker.service.ts, head server/src/maintenance/maintenance-worker.service.ts
        server/src/app.common.ts: site 9 'src/middleware/websocket.adapter.js' (import): base server/src.backup/middleware/websocket.adapter.ts, head server/src/middleware/websocket.adapter.ts
        server/src/app.common.ts: site 10 'src/repositories/config.repository.js' (import): base server/src.backup/repositories/config.repository.ts, head unresolved
        server/src/app.common.ts: site 11 'src/repositories/logging.repository.js' (import): base server/src.backup/repositories/logging.repository.ts, head unresolved
        server/src/app.common.ts: site 12 'src/repositories/telemetry.repository.js' (import): base server/src.backup/repositories/telemetry.repository.ts, head unresolved
        server/src/app.common.ts: site 13 'src/services/api.service.js' (import): base server/src.backup/services/api.service.ts, head unresolved
        server/src/app.common.ts: site 14 'src/utils/misc.js' (import): base server/src.backup/utils/misc.ts, head server/src/utils/misc.ts
        server/src/app.module.ts: site 10 'src/controllers/index.js' (import): base server/src.backup/controllers/index.ts, head server/src/controllers/index.ts
        … 4540 more
FAIL  K3c Resolution identity under the runtime: 2287 violations under nest-cli/emit (10.0 s)
        server/src/app.common.ts: nest-cli/emit: import 'src/maintenance/maintenance-worker.service.js' (emitted as './maintenance/maintenance-worker.service.js') resolves to server/src/maintenance/maintenance-worker.service.ts, expected server/src.backup/maintenance/maintenance-worker.service.ts; base server/src/app.common.ts 'src/maintenance/maintenance-worker.service.js'
        server/src/app.common.ts: nest-cli/emit: import 'src/middleware/websocket.adapter.js' (emitted as './middleware/websocket.adapter.js') resolves to server/src/middleware/websocket.adapter.ts, expected server/src.backup/middleware/websocket.adapter.ts; base server/src/app.common.ts 'src/middleware/websocket.adapter.js'
        server/src/app.common.ts: nest-cli/emit: import 'src/repositories/config.repository.js' resolves to unresolved (ERR_MODULE_NOT_FOUND), expected server/src.backup/repositories/config.repository.ts; base server/src/app.common.ts 'src/repositories/config.repository.js'
        server/src/app.common.ts: nest-cli/emit: import 'src/repositories/logging.repository.js' resolves to unresolved (ERR_MODULE_NOT_FOUND), expected server/src.backup/repositories/logging.repository.ts; base server/src/app.common.ts 'src/repositories/logging.repository.js'
        server/src/app.common.ts: nest-cli/emit: import 'src/repositories/telemetry.repository.js' resolves to unresolved (ERR_MODULE_NOT_FOUND), expected server/src.backup/repositories/telemetry.repository.ts; base server/src/app.common.ts 'src/repositories/telemetry.repository.js'
        server/src/app.common.ts: nest-cli/emit: import 'src/services/api.service.js' resolves to unresolved (ERR_MODULE_NOT_FOUND), expected server/src.backup/services/api.service.ts; base server/src/app.common.ts 'src/services/api.service.js'
        server/src/app.common.ts: nest-cli/emit: import 'src/utils/misc.js' (emitted as './utils/misc.js') resolves to server/src/utils/misc.ts, expected server/src.backup/utils/misc.ts; base server/src/app.common.ts 'src/utils/misc.js'
        server/src/app.module.ts: nest-cli/emit: import 'src/controllers/index.js' (emitted as './controllers/index.js') resolves to server/src/controllers/index.ts, expected server/src.backup/controllers/index.ts; base server/src/app.module.ts 'src/controllers/index.js'
        … 293 more
        finding (added-file-unresolved) server/src.backup/app.common.ts: nest-cli/emit: import 'src/repositories/config.repository.js' doesn't resolve (ERR_MODULE_NOT_FOUND) in a file with no base counterpart
        finding (added-file-unresolved) server/src.backup/app.common.ts: nest-cli/emit: import 'src/repositories/logging.repository.js' doesn't resolve (ERR_MODULE_NOT_FOUND) in a file with no base counterpart
        finding (added-file-unresolved) server/src.backup/app.common.ts: nest-cli/emit: import 'src/repositories/telemetry.repository.js' doesn't resolve (ERR_MODULE_NOT_FOUND) in a file with no base counterpart
        … 18 more findings
FAIL  K4  Location scan: 12 path-exposing uses in moved files (and 15 in added files), 2 computed paths into changed directories, 52 old paths in code/config (0 in coverage settings) (7.5 s)
        server/src/main.ts: moved to server/src.backup/main.ts; line 101: import.meta.filename: dirname(import.meta.filename) pointed at server/src (exists in base), now at server/src.backup (exists in head)
        server/src/main.ts: moved to server/src.backup/main.ts; line 116: new Worker(workerFile) (worker_threads)
        server/src/repositories/database.repository.ts: moved to server/src.backup/repositories/database.repository.ts; line 510: import(filePath) with a computed specifier (resolved relative to this file)
        server/src/repositories/database.repository.ts: moved to server/src.backup/repositories/database.repository.ts; line 511: import.meta.dirname: join(import.meta.dirname, '..', 'schema/migrations') pointed at server/src/schema/migrations (exists in base), now at server/src.backup/schema/migrations (exists in head)
        server/src/repositories/storage.repository.spec.ts: moved to server/src.backup/repositories/storage.repository.spec.ts; line 38: process.cwd()
        server/src/services/cli.service.ts: moved to server/src.backup/services/cli.service.ts; line 25: import.meta.dirname: join(import.meta.dirname, '../schema/migrations') pointed at server/src/schema/migrations (exists in base), now at server/src.backup/schema/migrations (exists in head)
        server/src/services/library.service.spec.ts: moved to server/src.backup/services/library.service.spec.ts; line 888: process.cwd()
        server/src/services/library.service.spec.ts: moved to server/src.backup/services/library.service.spec.ts; line 1284: process.cwd()
        … 73 more
        finding (stack-text) server/src/main.ts: moved to server/src.backup/main.ts; 1 stack-trace reads passed along as text (line 129); their frames now name the new path
        finding (stack-text) server/src/repositories/metadata.repository.ts: moved to server/src.backup/repositories/metadata.repository.ts; 1 stack-trace reads passed along as text (line 133); their frames now name the new path
        finding (stack-text) server/src/repositories/websocket.repository.ts: moved to server/src.backup/repositories/websocket.repository.ts; 1 stack-trace reads passed along as text (line 95); their frames now name the new path
        … 54 more findings
FAIL  K6  Test inventory: vitest 4.1.11: 189 violations (100 of 105 test files fail to load (base: 0), 4 files that no longer load, 96 dropped test files, 89 new test files, 2285 lost tests) (53.7 s)
        server/src/controllers/activity.controller.spec.ts: no longer in the vitest test list (now at server/src.backup/controllers/activity.controller.spec.ts)
        server/src/controllers/album.controller.spec.ts: no longer in the vitest test list (now at server/src.backup/controllers/album.controller.spec.ts)
        server/src/controllers/api-key.controller.spec.ts: no longer in the vitest test list (now at server/src.backup/controllers/api-key.controller.spec.ts)
        server/src/controllers/app.controller.spec.ts: no longer in the vitest test list (now at server/src.backup/controllers/app.controller.spec.ts)
        server/src/controllers/asset-media.controller.spec.ts: no longer in the vitest test list (now at server/src.backup/controllers/asset-media.controller.spec.ts)
        server/src/controllers/asset.controller.spec.ts: no longer in the vitest test list (now at server/src.backup/controllers/asset.controller.spec.ts)
        server/src/controllers/auth.controller.spec.ts: no longer in the vitest test list (now at server/src.backup/controllers/auth.controller.spec.ts)
        server/src/controllers/config.controller.spec.ts: no longer in the vitest test list (now at server/src.backup/controllers/config.controller.spec.ts)
        … 181 more
FAIL  K8  Oracles on the commit: tsc exited 1 on head (768 diagnostics), 0 on base; unit 5/105 files and 52/2,337 cases equal to base (head: 5/105 files load, 52 passed, 0 failed, 0 skipped); openapi produced nothing (39.3 s)
        tsc: `node_modules/.bin/tsc --noEmit --incremental false --pretty false` exited 1 on head (768 diagnostics), exit 0 on base (log /tmp/ac-s4-certify/g3-immich-opencode-super-persistent.full/oracles/head/tsc/step-1.log)
        server/src/bin/sync-sql.ts: tsc: TS1002 Unterminated string literal.
        server/src/bin/sync-sql.ts: tsc: TS1002 Unterminated string literal.
        server/src/bin/sync-sql.ts: tsc: TS1002 Unterminated string literal.
        server/src/bin/sync-sql.ts: tsc: TS1002 Unterminated string literal.
        server/src/bin/sync-sql.ts: tsc: TS1002 Unterminated string literal.
        server/src/bin/sync-sql.ts: tsc: TS1002 Unterminated string literal.
        server/src/bin/sync-sql.ts: tsc: TS1002 Unterminated string literal.
        … 206 more

verdict: FAIL (static checks and oracles)
digest: sha256:90d2d44bbd647b5f1b99d61590fbaa9f993572e244c7a8e91fd60c1b0161651e

Ac-Certificate: fail (full) K0=pass K1=fail K2=pass K3=fail K4=fail K6=fail K8=fail
Ac-Certificate-Base: 02063972e82b1bfd17b6fc2e3b3ff39936229ea5
Ac-Certificate-Digest: sha256:90d2d44bbd647b5f1b99d61590fbaa9f993572e244c7a8e91fd60c1b0161651e

Rendered by ac report from the run dir; the certificate files sit next to this page.