Skip to content

FDR-0019: Implement scoped repo resolution prototype#271

Open
friedenberg wants to merge 1 commit into
masterfrom
claude/fdr-scoping-repo-ids-opywye
Open

FDR-0019: Implement scoped repo resolution prototype#271
friedenberg wants to merge 1 commit into
masterfrom
claude/fdr-scoping-repo-ids-opywye

Conversation

@friedenberg

Copy link
Copy Markdown
Collaborator

Implements the dodder-side prototype for FDR-0019 (Scoped Repo Resolution), allowing multiple named repositories to coexist per scope under a repos/<name>/ layout while maintaining independent metadata trees.

Summary

This PR introduces a new repo_id.Id type that extends the legacy location-only selector (., /, empty) with an optional name and cwd dot-depth, mirroring madder's blob_store_id grammar. Named repos are addressed via the -repo_id flag and DODDER_REPO_ID environment variable, with each repo maintaining fully isolated metadata (config, index, inventory log, lock) while sharing the content-addressed blob store.

Key Changes

  • New internal/bravo/repo_id package: Implements the FDR-0019 grammar parser with Id type supporting:

    • User scope: name or ~name (parse-only alias)
    • Cwd scope: .name or ..name (dot-depth; multi-dot rejected by prototype)
    • System scope: //name or /name (remote-first not implemented)
    • Legacy nameless forms: ., /, empty (auto)
    • Canonical string rendering (single-dot form, no depth)
    • Validation of names (alphanumeric, underscore, hyphen only)
  • env_dir.NestUnderRepoName: New function that appends repos/<name>/ to dodder's XDG category directories (data/config/state/cache/runtime), so a named repo's entire metadata tree nests automatically. Blob store XDG is deliberately NOT nested (madder re-derives it, discarding suffixes).

  • Integration points: Wired repo_id.Id into three env-construction sites:

    • MakeEnvRepo: Applies nesting for reads
    • OnTheFirstDay (genesis): Applies nesting for initialization
    • MakeLocalWorkingCopyWithOptions: Applies nesting for working copy access
    • All three sites call CheckPrototypeSupported() to reject multi-dot cwd depth
  • CLI/config: Updated repo_config_cli.Config.RepoId to use repo_id.Id instead of madder's env_dir.RepoId; updated flag help text to document the full grammar.

  • Genesis idempotency: Modified writeBlobStoreConfigIfNecessary to tolerate pre-existing blob store config, allowing multiple named repos in the same scope to share madder's content-addressed blob pool.

  • Tests:

    • Unit tests (repo_id/main_test.go): Grammar parsing, canonical round-trip, error cases, depth gate
    • Integration tests (scoped_repos.bats): Two user-scoped named repos isolated, DODDER_REPO_ID addressing, multi-dot rejection

Notable Implementation Details

  • Prototype limitations (by design, pending madder env_dir.RepoId change):

    • Empty id resolves to legacy user scope (not FDR's "nearest cwd repo on walk-up, else user default"), preserving backward compatibility
    • Only single-dot cwd depth (.name) resolves; ..name parses but is rejected at resolution
    • /name resolves straight to system scope; remote-first lookup not implemented
    • Blob store remains shared across named repos (full isolation waits on madder change)
  • Madder projection: Id.GetMad() converts to madder's legacy env_dir.RepoId for scope routing, so existing MakeDefaultAndInitialize logic continues working unchanged.

  • Documentation: Added docs/plans/2026-06-14-fdr-0019-scoped-repos-prototype.md explaining the prototype scope, limitations, and path to the full FDR implementation.

https://claude.ai/code/session_01KnD7hCXXKPqnX1SG4ofL5S

Implement the user-visible slice of FDR-0019 entirely within dodder,
ahead of the madder env_dir.RepoId grammar change the FDR ultimately
routes through. Several named repos can now coexist per scope under a
repos/<name>/ layout and are addressed by the name portion of -repo_id
(and DODDER_REPO_ID).

- internal/bravo/repo_id: new location selector type parsing the FDR
  grammar (name / .name / ..name / //name / /name / ~name, plus the
  legacy nameless . / / / empty) with canonical single-dot String().
- env_dir.NestUnderRepoName: append repos/<name>/ to the dodder XDG
  category dirs so a named repo's whole metadata tree nests. Wired into
  MakeEnvRepo, genesis OnTheFirstDay, and MakeLocalWorkingCopy.
- repo_config_cli: -repo_id / DODDER_REPO_ID accept the full grammar.
- env_repo genesis: tolerate a pre-existing default blob store config
  so named repos in one scope share the content-addressed blob pool
  while keeping independent metadata/index/identity.

Prototype limitations (documented): blobs are shared not isolated
(madder re-derives the blob-store XDG); empty id stays legacy user
scope; only single-dot cwd depth resolves (..name rejected); /name
resolves to system scope (remote-first not implemented).

Tests: repo_id grammar unit tests; scoped_repos.bats covers two
user-scoped named repos isolated, DODDER_REPO_ID addressing, and
multi-dot rejection.

Docs: docs/plans/2026-06-14-fdr-0019-scoped-repos-prototype.md.

https://claude.ai/code/session_01KnD7hCXXKPqnX1SG4ofL5S
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants