Repository navigation
feat(metadata): repository descriptions and owner profiles - #97
Open
jonasgrosch wants to merge 1 commit into
Open
jonasgrosch wants to merge 1 commit into
jonasgrosch wants to merge 1 commit into
Conversation
Opaque owner/repo ids (UUIDs from another system) leave the owner list and
repo lists unreadable: walgit has nowhere to keep the name a person reads.
Two small control objects, shaped like policy.json (D16) and for the same
reasons not on the WAL (D50):
- repos/<o>/<r>/description.json {"description"}
GET|PUT|DELETE /{o}/{r}/api[-browser]/description; create accepts
?description= (admin, validated before anything is created);
`walgit repo describe <repo> [--set TEXT|--clear]`.
- owners/<o>/profile.json {"display_name","description"}
GET|PUT|DELETE /api[-browser]/v1/owners/{owner}. Bucket root, not under
repos/: that prefix holds repositories only and its delimited listing is
how the registry finds them. Owners stay implicit: a profile creates
nothing and is listed only while its owner has a repository.
- ?detail=1 on /api/v1/owners and /api/v1/owners/{o}/repos returns objects
with the metadata; the plain string[] shapes are unchanged.
Read for GET, admin for every write. One line of plain text, bounded
(description 512, display_name 100 chars, 8 KiB body/object); strict on
write (unknown keys, non-strings, control characters -> 400, 413 above the
bound), lenient on read (unknown keys ignored for rolling binaries; an
unparsable or oversized object reads as absent). Metadata answers are SWR
with a body-digest ETag.
Also: the owner listings were routed on /api/v1 only while the SDK's
browser lane addresses /api-browser/v1/owners*; all owners* routes are now
on both lanes.
UI: the home page shows display_name first with the id beside it, the owner
page shows the profile and each repository's description, the repo header
shows the description. SDK: owners.listDetail/reposDetail/profile.*,
repo.description.*, create({description}).
Round trips (docs/ROUNDTRIPS.md row added):
- git paths, push, every sync, plain listings: before = after (0 extra).
- GET description / owner profile: 1 object GET, the description's
concurrent with the repository-exists check (depth 1 on a warm handle).
- ?detail=1: listing + one GET per listed owner resp. repository, 32 in
flight, depth ceil(n/32) after the listing. Opt-in only.
- No CAS'd object is written; no manifest write; no in-process cache
(principle IV; policy.json is read the same way).
Git's own `description` file is not written: the bare repository is a
disposable per-instance cache and nothing git serves reads it; keeping it
correct would need a hook on every materialization and every change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Author
|
Heads-up from our integration of the #94 PRs (proxy mode + metadata + default HEAD + baseline together, full workspace suite green): with this PR and #97 both merged, 🤖 Generated with Claude Code |
This was referenced Sep 30, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Deployments that use opaque ids (e.g. UUIDs) as owners/repositories have nowhere to keep a human-readable name, so the home page and repository lists are unreadable. Two small control objects, shaped like
policy.jsonand kept off the WAL:repos/<o>/<r>/description.json{"description"}.GET|PUT|DELETE /{o}/{r}/api[-browser]/description;PUT /{o}/{r}?description=…at create time;walgit repo describe <repo> [--set TEXT|--clear].owners/<o>/profile.json{"display_name","description"}.GET|PUT|DELETE /api[-browser]/v1/owners/{owner}. At the bucket root becauserepos/holds repositories only (its delimited listing is how they are found). Owners stay implicit: a profile creates nothing and is listed only while its owner has a repository.?detail=1on/api/v1/ownersand/api/v1/owners/{o}/reposreturns objects with the metadata; the plainstring[]shapes are unchanged.GET needs read; every write needs admin — including
?description=on create, becauseRegistry::createalso answersOk/201 for a repository already open on the instance (so a create does not prove newness; worth fixing separately). Fields are one line of plain text, bounded (512 / 100 chars, 8 KiB documents); writes strict, reads lenient (unknown keys ignored for rolling binaries). Metadata answers are SWR with a body-digestETag.Also fixes a gap: the SDK's browser lane addressed
/api-browser/v1/owners*, which was never routed; allowners*routes now exist on both lanes.UI: owners show their display name (id beside it), the owner page lists repository descriptions, the repo header shows the description. SDK:
owners.listDetail(),owners.reposDetail(),owners.profile.*,repo.description.*,repo.create({description}).Round trips (ROUNDTRIPS.md row added): git paths, pushes, syncs, plain listings unchanged. A description/profile GET = 1 object GET.
?detail=1= the listing + one GET per item, 32 in flight — opt-in per call, and the UI's home page uses it. A conditional-GET cache would cut the steady state further; left out to keep "every read revalidates" untouched.Tests: validation, lenient reads, serialization;
api_v1::descriptions_and_owner_profiles(auth 401/403/204, both lanes, ETag → 304, 400/413 limits, unknown repo → 404, create-with-description, detail listings with absent fields, delete removes the description).pnpm run buildpasses.Part of #94. Each of these PRs claims the next decision number in
AGENTS.md(D50/D5x); renumber on merge as you prefer.🤖 Generated with Claude Code