Skip to content

rfc: named targets and CLI coherency - #675

Merged
aaltshuler merged 17 commits into
mainfrom
codex/config-cli-coherency
Oct 20, 2026
Merged

aaltshuler merged 17 commits into
mainfrom
codex/config-cli-coherency

Conversation

@aaltshuler

@aaltshuler aaltshuler commented Sep 6, 2026 •

Copy link
Copy Markdown
Contributor

Accept RFC 0059's breaking CLI target contract for 0.14.0: select one complete destination through --target NAME|ADDRESS, otherwise defaults.target, otherwise refuse. Keep --config for source input, retain init URI, and remove legacy selectors and routing through one explicit target import migration.

The RFC defines endpoint-bound credentials, bootstrap and source-free recovery, canonical binding identity, target/credential protocol discovery, and captured provider settings shared by control storage and Lance. It updates the seven earlier RFCs whose routing sections this decision replaces. Existing command families remain; access reporting, local serving and the CLI MCP bridge are separate work.

This PR accepts the design only. Implementation remains in progress in #1090 and must complete its provider-boundary, protocol, reporting and current-main qualification before release. #1080 was closed in favor of that implementation.

Validation: documentation checker (350 Markdown files), AGENTS/document index checks, spelling checks on all changed documents, and git diff --check. A separate coherence review found no documentation merge blocker. No runtime code changes or new runtime-test claims.

aaltshuler added a commit that referenced this pull request Sep 16, 2026
Managed queries and mutations can outlast the current 10-second deadline. Allow 30 seconds for connection and the complete response, retaining the 10-second connection limit, 8 MiB response bound, and no redirects or automatic retries. A timed-out mutation can have committed and must be reconciled before resubmission.

Prepare the existing load and commit-read transports to use the same bounded response decoder. Managed load limits the exact UTF-8 request to 32 MiB and waits at most 300 seconds for its receipt. This PR does not activate managed routing for load or commit commands. Version-1 signed-grant fixtures retain their existing compatibility contract; they do not require other identity credentials to carry graph permissions.

The implemented boundary is recorded in accepted RFC 0053. The broader named-connection proposal in #675 is not part of this change. Upcoming release notes are in v0.12; released v0.11 notes are unchanged.

Validation at the rebased head: 14 focused managed unit tests and eight CLI routing tests passed, as did the canonical workspace/failpoint graph with CI's documented 16 MiB debug stack setting. Formatting, documentation checks, spelling and diff checks passed. All GitHub checks are green, including full workspace, GQ, AWS server, both RustFS suites and genuine-version upgrade/format checks. The initial local default-stack overflow in an unchanged cluster test was reproduced and passed with the existing CI setting; no source workaround was added.
aaltshuler added a commit that referenced this pull request Sep 16, 2026
Signed credentials currently duplicate graph/action permissions already held in policy. Version 2 credentials authenticate a principal for one cluster; the applied Cedar policy owns graph, schema and configuration permissions. Minimal discovery exposes every effective graph ID/name without granting access to data, schema or query definitions.

The shared cluster API authorizes the complete configuration plan against current applied policy, repeats checks under the existing lock, and refuses candidate self-grants, changed bases and pending recovery. Initial policy installation uses an exact first-initialization boundary. The new recovery probe inspects bounded storage metadata without opening or repairing the graph.

The CLI preserves complete typed HTTP errors for both `--json` and `--format json`. Denial regressions verify structured errors and unchanged graph snapshots/branch inventory.

Compatibility:

- Normal managed issuance uses identity-only credentials. Published version-1 restricted credentials remain an explicit OSS compatibility profile and are never silently upgraded.
- Direct/static authentication and storage-holder entry points retain their contracts.
- Existing policy files need an explicit `config_manage` rule before identity-authorized configuration execution. Public exhaustive policy matches need the new `ConfigManage`/`Cluster` variants.
- This change introduces no stored graph format change. It does not implement the configuration proposal in #675.

The accepted design is `docs/rfcs/2026-09-09-identity-credentials-and-applied-policy.md`. This PR builds on the merged bounded-transport change in #685.

Validation: the JSON-format failure was reproduced before the fix; four focused remote CLI tests and six policy-enforcement cases pass. Formatting, documentation and link checks pass; recovery code and tests use current seam APIs. On the final head, canonical local workspace/failpoint tests pass (3,182 passed, 25 ignored), as do 149 GQT library and 14 runner-dispatch tests. Full workspace, GQ, DST, server AWS, both RustFS suites and format/upgrade CI pass. Locally unconfigured cloud/predecessor fixtures are qualified by their configured CI jobs.
@aaltshuler aaltshuler changed the title docs: RFC 0059 and configuration/CLI framework docs: revise configuration/CLI proposal for remaining connection selection gaps Oct 7, 2026
@aaltshuler

Copy link
Copy Markdown
Contributor Author

The 0.13 audit leaves a smaller unresolved scope here. #878 replaced the deployment/CLI baseline, and #676 already covered part of the targeting problem. The draft must be rewritten before acceptance; it should not merge as written or be closed as implemented.

Carry forward explicit managed data connections/profiles/aliases, independently selected endpoint/credential binding, and the tests that prove destination and credential choice. Keep #653 as its separate served-catalog feature. Rebase the design on the current v2 identity and cluster ... --managed contracts, without restoring removed commands, aliases, credentials or compatibility layers. Extract or revise those requirements before retiring this PR.

@aaltshuler aaltshuler changed the title docs: revise configuration/CLI proposal for remaining connection selection gaps docs: redesign CLI targeting in RFC 0059 Oct 14, 2026
Comment thread docs/rfcs/0059-config-cli-coherency.md Outdated
Comment thread docs/rfcs/0059-config-cli-coherency.md Outdated
Comment thread docs/rfcs/0059-config-cli-coherency.md Outdated
Comment thread docs/rfcs/0059-config-cli-coherency.md Outdated
Comment thread docs/rfcs/0059-config-cli-coherency.md Outdated
Comment thread docs/rfcs/0059-config-cli-coherency.md
Comment thread docs/rfcs/0059-config-cli-coherency.md Outdated
Comment thread docs/rfcs/0059-config-cli-coherency.md Outdated
Comment thread docs/rfcs/0059-config-cli-coherency.md Outdated
Comment thread docs/rfcs/0059-config-cli-coherency.md Outdated
@ragnorc

ragnorc commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

@aaltshuler, a heads-up on a decision in #1017 that touches 0059. There is nothing for you to approve; I'd like you to have the reasoning before your next revision.

#1017 now defines omnigraph targets as the one exception to 0059's "Add no target administration group":

  • omnigraph targets --json lists targets and aliases through 0059's resolver, with no secrets and no network request.
  • omnigraph targets add NAME --json (the entry on stdin) and omnigraph targets remove NAME change only that entry. They validate through 0059's resolver, write atomically, never touch defaults.target, never store a secret (tokens stay with login --target), and refuse in a legacy-format home.

Why. Studio has to add servers. Without a CLI writer it can only write config.yaml itself, which makes it a second writer of a file 0059 validates strictly and can collide with a person's edit; ask people to edit YAML; or keep its own server list, which it does today. A separate list means the agents Studio runs, which use the CLI, cannot see servers that exist only in Studio, and a token rotated with login leaves Studio holding the old one. A writer adds no selection command and no current-target state, which is what the rule protects against. git config, kubectl config set-context and gh config set play the same part for their tools, and the CLI already writes the credentials file through login.

Where #1017 follows 0059 as of 323068fa: every new command selects with --target, then defaults.target, takes no legacy selector during your compatibility interval, and refuses in a legacy-format home. credential resolves the token owner and checks its endpoint scope, and the listing reports token or anonymous. Rows for serve, studio, mcp, credential, targets and --session live in #1017's command table until 0059 has them.

When 0059 is accepted, it would help if its "no administration group" line named targets as the exception, so the two RFCs agree. I can send exact text as a PR against your branch if that's easier.

Details: Targets for clients in #1017.

@ragnorc

ragnorc commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Heads-up: #1080 (draft) implements named targets on the format sketched here, as an additive first step for the graph access RFC (#1017, its "Targets" phase). Everything in it is provisional until this RFC accepts the serialized format, so please redirect anything that should change.

What it reads:

target_config_version: 1
defaults:
  target: staging
targets:
  local:   {kind: direct, scope: graph, uri: file:///Users/me/company.omni}
  ops:     {kind: direct, scope: root, uri: s3://company-data/omnigraph, default_graph: knowledge}
  staging: {kind: server, endpoint: https://staging.example, credential: staging, default_graph: knowledge}
  public:  {kind: server, endpoint: https://public.example, auth: anonymous}

Choices worth your eye:

  1. Anonymous access is explicit: a server target names credential: OWNER or sets auth: anonymous, never neither.
  2. The owner is bound to the endpoint: the file refuses an owner at two endpoints, two owners for one endpoint, and an anonymous target beside a keyed one; a servers: name may be an owner only at that server's url. Tokens go only to URLs under the endpoint, by the sent-URL matching servers: already use.
  3. Direct uri must be absolute (path or file:///s3:///az://); resolving relative paths against the operator file is not implemented yet.
  4. Strictness: unknown fields, an unsupported target_config_version or a malformed name refuse the file; an incomplete entry refuses only when selected.
  5. target list|show|add|remove exists, the exception rfc: graph access and cross-process writes #1017 argues for; add/remove edit one entry's lines and keep the rest of the file. No selection command or current-target state.
  6. Additive: --server, --store, --profile, servers: and profiles: keep working in feat(cli): name targets in the operator configuration #1080, and --target refuses them beside it; retiring them and adding managed targets would be later changes.

…inistration

One release ships the target contract and removes every retired
selector, routing section and their commands, with no compatibility
adapters and no mixed-format operator file; `target import` converts a
legacy file and `--quiet` is removed.

`--target` also takes an inline address, a storage path or URI or a
server endpoint, as a complete binding scoped from the command line
alone. An inline server carries a token only under a configured
owner's endpoint scope, an inline cloud URI captures its provider
settings once for the invocation, `init URI` is the positional form and
managed destinations stay named.

`target list|show|add|remove|import` and `credential get` edit and read
operator config and the credentials file; none selects a target or sets
the default.
@ragnorc

ragnorc commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Pushed bf9bcce with three decisions from Ragnor:

  • Breaking, one release. The release that ships the target contract removes every retired selector, routing section and their commands (use, profile, --quiet). There are no compatibility adapters, and no operator file mixes the two formats: a legacy file refuses and names target import, which converts it in one edit, keeping credential owners and their endpoint scopes.
  • Inline targets. --target also takes a storage path or URI, or a server endpoint, as a complete binding. A value containing / or : is never a name. The command line alone decides the scope: --graph or a root-only command makes a storage address a root. An inline server carries a token only under a configured owner's endpoint scope. An inline cloud URI captures its provider settings once for the invocation, as literal init already did. init URI is the positional form, and managed destinations stay named.
  • Target administration. target list|show|add|remove|import and credential get read and edit operator config and the credentials file. None of them selects a target or sets the default.

The decision log records them, and the compatibility, test and rollout sections follow. #1080 implements the schema, validation, endpoint-bound credentials and administration commands for direct and server targets.

@aaltshuler aaltshuler changed the title docs(rfc): unify CLI targeting in RFC 0059 rfc: named targets and CLI coherency Oct 20, 2026
@aaltshuler
aaltshuler marked this pull request as ready for review October 20, 2026 10:27
@aaltshuler
aaltshuler added this pull request to the merge queue Oct 20, 2026
Merged via the queue into main with commit 9f2523c Oct 20, 2026
33 checks passed
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.

3 participants