Review of the SCM implementation against the specification at specs/scm-system.md.
| Category | Implemented | Partial | Missing |
|---|---|---|---|
| Core Features | 7 | 2 | 1 |
| Total | 7 | 2 | 1 |
- Repos can belong to users or orgs: ✅ Implemented via
OwnerType::User | Orgin types.rs - Visibility (private/public): ✅
Visibility::Private | Publicwith private as default - UUID-based filesystem layout with sharding: ✅ Implemented in git.rs routes using
{shard}/{uuid}/git/pattern - Database schema: ✅ Matches spec exactly in schema.rs
- Clone URL format: ✅
https://loom.ghuntley.com/git/{owner}/{repo}.git - Routes in git.rs:
GET /git/{owner}/{repo}/info/refsPOST /git/{owner}/{repo}/git-upload-packPOST /git/{owner}/{repo}/git-receive-pack
- Credential helper in loom-cli: ✅ Full implementation in credential_helper.rs
- Supports
get,store,eraseoperations - Returns
username=oauth2, password={session_token} - Uses stored token from
loom login
- Supports
- Weaver auto-injected credentials:
⚠️ NOT VERIFIED - No code found that injects credentials into weavers for SCM. The spec says credentials should be auto-injected when a weaver is launched, but no implementation was found linking weaver launch to SCM credential injection.
- Repo-level roles (read, write, admin): ✅
RepoRoleenum defined in types.rs - Team-based access:
⚠️ Schema only -repo_team_accesstable exists in schema.rs andRepoTeamAccesstype exists, but:- No
RepoTeamAccessStoretrait or implementation - No API endpoints for managing team access
- Not used in access control checks in the server
- No
- Who can grant access:
⚠️ Partially - repo owner checks exist, but formal role-based access grant API is missing
Missing:
- API endpoints:
GET/POST/DELETE /api/v1/repos/{id}/access - Team access management endpoints
- Integration of team access in permission checks
- Pattern matching (e.g., 'cannon', 'release/*'): ✅ protection.rs
- Block direct push, force-push, deletion: ✅ All three options supported
- Admins can bypass: ✅
user_is_admincheck incheck_push_allowed - API endpoints: ✅ All three endpoints implemented in protection.rs routes
- Git receive-pack integration: ✅ Protection rules checked during push in git.rs
- Create via API (not push-to-create): ✅
POST /api/v1/reposin repos.rs - Soft delete (recoverable): ✅
DELETE /api/v1/repos/{id}setsdeleted_at - Default branch is 'cannon': ✅ Hardcoded in types.rs
- Creates bare git repo on disk: ✅ Uses
GitRepository::init_bare()via gitoxide
- push.rs - Full implementation
- Branch rules with pattern matching
- Credential integration via
loom-credentials - Missing API endpoints: No routes found for:
GET /api/v1/repos/{id}/mirrorsPOST /api/v1/repos/{id}/mirrorsDELETE /api/v1/repos/{id}/mirrors/{mid}POST /api/v1/repos/{id}/mirrors/{mid}/sync
- pull.rs - Cloning and fetching
- Supports GitHub and GitLab platforms
check_repo_exists()API check
- cleanup.rs - Stale mirror cleanup
- 3-month threshold (configurable via
stale_afterduration) - Job integration in mirror_cleanup.rs
Missing:
- Mirror management API endpoints (CRUD operations)
- Integration with weaver launch for auto-mirroring
mirrors/github/{owner}/{repo}namespace handling
- Per-repo webhooks: ✅ webhooks.rs routes
- Org-level webhooks: ✅ Same file, org endpoints
- HMAC-SHA256 signature: ✅ delivery module
- GitHub-compat and Loom-v1 payload formats: ✅ payload module
- Retry with job scheduler: ✅
webhook_deliveriestable with retry logic - Events: ✅
push,repo.created,repo.deleted
Based on the directory structure at web/loom-web/src/routes/(app)/repos/[owner]/[repo]/:
| Feature | Status | Route |
|---|---|---|
| File browser | ✅ | tree/ |
| Commit history | ✅ | commits/ |
| Commit detail | ✅ | commit/ |
| Blame | ✅ | blame/ |
| Branch comparison | ✅ | compare/ |
| File view | ✅ | blob/ |
| Settings | ✅ | settings/ |
| Branches | ✅ | branches/ |
| Syntax highlighting | ❓ | Not verified |
| Open in Weaver button | ❓ | Not verified (needs code review) |
Likely complete but would need to inspect individual component files to confirm syntax highlighting and "Open in Weaver" button.
- Tasks (gc, prune, repack, fsck): ✅ maintenance.rs
- Per-repo maintenance: ✅
POST /api/v1/repos/{id}/maintenance - Global sweep: ✅
POST /api/v1/admin/maintenance/sweep - Staggered execution: ✅
stagger_delayparameter inrun_global_sweep - Job tracking: ✅
repo_maintenance_jobstable with full status tracking - API endpoints: ✅ maintenance.rs routes
-
Route pattern: Spec says
/git/{owner}/{repo}.git/info/refsbut implementation uses/git/{owner}/{repo}/info/refs(without.gitsuffix in path). The.gitsuffix is stripped from the repo name parameter instead. -
User resolution in Git routes: The spec implies user repos can be resolved via username, but the current implementation only resolves org repos via slug. User repos by username may not work.
- Team-based access control API - Schema exists but no endpoints or integration
- Mirror management API endpoints - Core mirroring works but no CRUD API
- Weaver auto-credential injection - No code linking weaver launch to SCM credentials
- User repo access via username in Git routes - Only org slug resolution implemented
- Open in Weaver button - Web UI route exists but button presence not verified
- Syntax highlighting - File browser exists but highlighting not verified
- High Priority: Implement mirror management API endpoints to allow users to configure push mirrors
- High Priority: Implement team access management endpoints and integrate into permission checks
- Medium Priority: Add weaver credential injection for SCM access
- Low Priority: Add user repo resolution by username in Git HTTP routes
- Low Priority: Verify Web UI features (syntax highlighting, Open in Weaver)