Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ body:
options:
- configure
- update
- organization
- db
- fs
- fs-git
Expand Down
68 changes: 27 additions & 41 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,20 @@ Implemented:
`docs/spec/done/0003-output-error-query-dry-run.md`
- API client auth, authorization, and region routing from
`docs/spec/done/0004-api-client-auth-and-region-routing.md`
- Organization project listing from
`docs/spec/done/0005-organization-management.md`
- Historical organization project listing from
`docs/spec/done/0005-organization-management.md`, superseded by project
selection and inventory removal in `docs/spec/done/0029-remove-db-project-selection.md`
- Starter DB cluster lifecycle from
`docs/spec/done/0006-starter-db-cluster-lifecycle.md`
- Starter DB branch lifecycle from
`docs/spec/done/0007-starter-db-branch-lifecycle.md`
- Starter DB SQL access and query from
`docs/spec/done/0008-starter-db-sql-access-and-query.md`
- Default virtual project discovery and DB create resolution from
`docs/spec/done/0017-default-virtual-project-resolution.md`
- Historical default virtual project discovery from
`docs/spec/done/0017-default-virtual-project-resolution.md`, superseded by
project selection and inventory removal
- TiDB Cloud Project selection and inventory removal from
`docs/spec/done/0029-remove-db-project-selection.md`
- Starter-only DB resource guardrails from
`docs/spec/done/0023-starter-only-db-resource-guardrails.md`
- Region-scoped Starter DB cluster listing from
Expand Down Expand Up @@ -78,7 +82,6 @@ Implemented:
- `ti configure`
- `ti update --check`
- `ti update`
- `ti organization list-projects`
- `ti db create-db-cluster`
- `ti db list-db-clusters`
- `ti db describe-db-cluster`
Expand Down Expand Up @@ -204,7 +207,6 @@ make test
make e2e
make telemetry-e2e
make live-e2e-configure
make live-e2e-organization
make live-e2e-db
make live-e2e-fs
make live-e2e-fs-git
Expand Down Expand Up @@ -233,7 +235,7 @@ delivery path before dropping only that temporary database. It must not run as
part of `make test`, `make e2e`, or any live-e2e target.
The `make live-e2e-<family>` targets build `bin/ti` and run only the selected
top-level command family against the `live-e2e` profile by default. Keep
configure, organization, db, fs, fs-git, fs-journal, and fs-vault tests
configure, db, fs, fs-git, fs-journal, and fs-vault tests
independently selectable. Do not make a focused family target run tests from a
different family, and do not add separate mutating/non-mutating variants.
`make live-e2e` runs every live family together in one test process and remains
Expand All @@ -243,10 +245,9 @@ Live e2e must strictly cover every implemented interface and command for the
current project stage, including real create/update/delete flows when those
commands are implemented. For Starter DB clusters, the live suite creates a
uniquely named `ti-e2e-*` cluster with `--wait`, without a
spending limit or explicit/configured project ID, verifies the returned state
is `ACTIVE` and has a non-empty server-selected project label, and deletes only
that cluster. The server-selected account default is not required to equal the
`tidbx_virtual` project discovered by `ti configure`. For Starter DB branches,
spending limit or project selection, verifies the returned state is `ACTIVE`,
preserves any server-selected project metadata, and deletes only that cluster.
For Starter DB branches,
the live suite creates, reads, lists, and deletes only a `ti-e2e-branch-*`
branch on the cluster created by the same test run. Branch creation must use
`--wait`; cluster deletion must use `--wait`. For Starter DB SQL access, the live suite prepares ti-managed
Expand Down Expand Up @@ -326,7 +327,6 @@ internal/fs/fscred/ ID-keyed ti fs credentials, selection, and legacy mi
internal/fs/mountlocator/ non-secret Drive9 background mount routing state
internal/oplog/ local JSONL operation log writer
internal/output/ structured JSON/text/raw rendering
internal/organization/ organization project command use cases
internal/query/ JMESPath query application
internal/secretinput/ no-echo secret input helper
internal/settings/ global settings parsing and legacy logging migration
Expand Down Expand Up @@ -354,7 +354,7 @@ Follow these rules unless `docs/priciples.md` is updated:
- The command tree is at most two levels: `ti <command> [subcommand]`.
- `ti configure` and `ti update` are the only intentional top-level verb
exceptions. `ti configure` is the only interactive command.
- Other top-level commands are nouns such as `db`, `fs`, and `organization`.
- Other top-level commands are nouns such as `db` and `fs`.
- Use long flags only, for example `--profile` and `--db-cluster-name`.
- Do not add short flags or one-letter aliases. The current CLI rejects short
flags before invoking Cobra.
Expand All @@ -363,7 +363,7 @@ Follow these rules unless `docs/priciples.md` is updated:
handlers as their canonical commands.
- Do not prompt for input except inside `ti configure`.
- Successful structured control-plane commands output JSON by default.
- Implement DB, organization, and fs control-plane commands through
- Implement DB and fs control-plane commands through
`controlPlaneCommandSpec` in `internal/cli`, so normal execution, dry-run,
output rendering, and query handling stay on the shared path.
- Non-DB control-plane commands must declare exactly one `authz.Permission` in
Expand Down Expand Up @@ -398,8 +398,8 @@ Follow these rules unless `docs/priciples.md` is updated:
legacy fallback, and dispatch through capability interfaces. Reject
recognized but unsupported products and missing, unknown, or conflicting
plans before the product operation.
- Only `ti db` uses dynamic operation-to-permission mapping. Keep FS and
organization command permissions static. The CLI composition root registers
- Only `ti db` uses dynamic operation-to-permission mapping. Keep FS command
permissions static. The CLI composition root registers
product resolvers/providers; the root `internal/db` package must not import
child product packages.
- `ti db list-db-clusters --db-cluster-type starter` adds an immutable API
Expand Down Expand Up @@ -469,13 +469,9 @@ Implemented command behavior:
- `ti update --dry-run`
- `ti update`
- `ti update --target-version v0.1.1`
- `ti organization list-projects`
- `ti organization list-projects --query 'projects[0].id'`
- `ti organization list-projects --output text`
- `ti db create-db-cluster --db-cluster-type starter --db-cluster-name demo`
- `ti db create-db-cluster --db-cluster-type starter --db-cluster-name demo --wait`
- `ti db create-db-cluster --db-cluster-type starter --db-cluster-name demo --dry-run`
- `ti db create-db-cluster --db-cluster-type starter --db-cluster-name demo --project-id <project-id>`
- `ti db list-db-clusters --db-cluster-type starter`
- `ti db list-db-clusters --db-cluster-type starter --query 'clusters[].id'`
- `ti db describe-db-cluster --db-cluster-id <cluster-id>`
Expand Down Expand Up @@ -593,7 +589,6 @@ Registered command surface:

- `ti update --check`
- `ti update`
- `ti organization list-projects`
- `ti db create-db-cluster`
- `ti db list-db-clusters`
- `ti db describe-db-cluster`
Expand Down Expand Up @@ -721,9 +716,9 @@ the deprecated variable name.
- The global `--profile` flag selects a profile when explicitly provided.
- The global `--region` flag selects command-scope placement when explicitly
provided and must reject an explicit empty value.
- `ti configure` writes canonical `region_code`, discovers the unique
`tidbx_virtual` project as `project_id`, and writes
`tidb_cloud_public_key` and `tidb_cloud_private_key`.
- `ti configure` writes canonical `region_code`, `tidb_cloud_public_key`, and
`tidb_cloud_private_key` without making a network request or discovering a
TiDB Cloud project.
- `ti configure --non-interactive` must not prompt. It reads values from flags
first, then `TI_REGION_CODE`, `TIDB_CLOUD_PUBLIC_KEY`, and `TIDB_CLOUD_PRIVATE_KEY`.
Missing values fail with an actionable error.
Expand All @@ -740,17 +735,16 @@ Typical configured profile keys:
# ~/.ti/config
[default]
region_code = "aws-us-east-1"
project_id = "..."

# ~/.ti/credentials
[default]
tidb_cloud_public_key = "..."
tidb_cloud_private_key = "..."
```

`project_id` is written by `ti configure` but is not required to create a
Starter cluster. If it is absent and `--project-id` is not provided, the create
request omits the project label and TiDB Cloud selects the account default.
Starter cluster creation never reads or sends project selection. It omits the
project label and lets TiDB Cloud select its server-side default project.
Project metadata returned by TiDB Cloud remains unchanged in command output.

One profile can access multiple remotely inventoried ti fs resources. The main
config stores neither a default resource nor resource credentials.
Expand Down Expand Up @@ -847,19 +841,11 @@ Placement lookup order for authenticated commands:
2. If `TI_REGION_CODE` is set, use it for this command only.
3. Otherwise use the selected profile's `region_code`.

Starter DB cluster creation project lookup order is:

1. Explicit non-empty `--project-id`.
2. The selected profile's `project_id`, discovered by `ti configure` from the
unique accessible project whose type is `tidbx_virtual`.
3. Otherwise omit the `tidb.cloud/project` label and let the Starter API select
the account's default project.

An explicitly empty `--project-id` is an error and must not use the profile
or server fallback. When no project ID resolves, omit the label entirely; do
not send `tidb.cloud/project` with an empty value. Other DB commands identify
existing resources by cluster or branch ID and do not send `project_id`.
Drive9-backed ti fs commands do not consume this DB project default.
Starter DB cluster creation omits project selection entirely. Do not expose a
`--project-id` flag, read a legacy profile `project_id`, or send a
`tidb.cloud/project` label. Preserve project-related fields and labels returned
by TiDB Cloud as opaque API resource metadata. Other DB commands identify
existing resources by cluster or branch ID.

Environment credentials are a credential source only; they must not change the
local profile namespace and must not cause ti to write local `[env]` sections.
Expand Down
5 changes: 1 addition & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ ifneq ($(strip $(TELEMETRY_ENDPOINT)),)
LDFLAGS += -X $(MODULE)/internal/version.telemetryEndpoint=$(TELEMETRY_ENDPOINT)
endif

.PHONY: all build build-telemetry-backend build-telemetry-migrator test e2e telemetry-e2e live-e2e live-e2e-configure live-e2e-organization live-e2e-db live-e2e-fs live-e2e-fs-git live-e2e-fs-journal live-e2e-fs-vault release-snapshot clean
.PHONY: all build build-telemetry-backend build-telemetry-migrator test e2e telemetry-e2e live-e2e live-e2e-configure live-e2e-db live-e2e-fs live-e2e-fs-git live-e2e-fs-journal live-e2e-fs-vault release-snapshot clean

all: build

Expand Down Expand Up @@ -58,9 +58,6 @@ live-e2e: build
live-e2e-configure: build
$(LIVE_E2E_RUN) -run '^TestLive(ProfileConfigured|CLICommandSurface)$$'

live-e2e-organization: build
$(LIVE_E2E_RUN) -run '^TestLiveOrganization'

live-e2e-db: build
$(LIVE_E2E_RUN) -run '^TestLiveDB'

Expand Down
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ The token contains its file system ID, so a clean sandbox does not need `TI_FS_F

Cluster lists include only verified Starter clusters in the effective region and omit other service plans, cross-region resources, and resources whose region cannot be verified. Use global `--region`, for example `ti --region aws-us-west-2 db list-db-clusters --db-cluster-type starter`, to inspect another region without changing the stored profile. Listing incrementally fills the requested result page from TiDB Cloud API pages. Its opaque `next_page_token` belongs to `ti` and can be passed only to a later call with the same profile, type, region, filter, and ordering.

`ti configure` discovers the account's virtual project and saves its ID in the selected profile. Cluster creation uses an explicit `--project-id` first, then that saved project ID. If neither is available, `ti` omits the project label and lets TiDB Cloud select the account's default project.
`ti configure` stores the selected profile's region and API keys locally without making a TiDB Cloud request. Cluster creation omits project selection and lets TiDB Cloud select its server-side default project. Project metadata returned by TiDB Cloud remains visible in the cluster response.

```shell
ti db create-db-cluster --db-cluster-type starter --db-cluster-name my-distributed-mysql --wait
Expand All @@ -216,7 +216,6 @@ ti db create-db-cluster --db-cluster-type starter --db-cluster-name my-distribut
```text
ti configure
ti update
ti organization list-projects

ti db create-db-cluster --db-cluster-type starter
ti db list-db-clusters --db-cluster-type starter
Expand Down Expand Up @@ -346,7 +345,6 @@ Run one live command family against the `live-e2e` profile:

```bash
make live-e2e-configure
make live-e2e-organization
make live-e2e-db
make live-e2e-fs
make live-e2e-fs-git
Expand Down
29 changes: 10 additions & 19 deletions docs/present.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,9 @@ TIDB_CLOUD_PRIVATE_KEY="$TIDB_CLOUD_PRIVATE_KEY" \
bin/ti configure --non-interactive
```

`configure` 会验证 TiDB Cloud API key,找到唯一的 `tidbx_virtual` project,并把其 ID 保存为默认 `project_id`。后续创建 Starter cluster 不需要重复传 `--project-id`
`configure` 只在本地保存 region 和 TiDB Cloud API key,不发送远端请求。第一个远端命令会验证对应权限;创建 Starter cluster 时由 TiDB Cloud 选择服务端默认 project。

## 1. 查看 Organization Project

```bash
bin/ti organization list-projects --output text
bin/ti organization list-projects --query 'projects[].{id:id,name:name,type:type}'
```

`organization` 当前是只读 control plane,可供人、脚本和 agent 检查 API key 能访问的项目。

## 2. 创建并管理 Starter Cluster
## 1. 创建并管理 Starter Cluster

为本次演示生成唯一名字:

Expand Down Expand Up @@ -91,7 +82,7 @@ bin/ti db create-db-cluster-branch \
bin/ti db list-db-cluster-branches --db-cluster-id "$CLUSTER_ID" --output text
```

## 3. 创建 SQL 用户并按角色执行 SQL
## 2. 创建 SQL 用户并按角色执行 SQL

创建或修复 ti 管理的三种稳定 SQL 用户。该操作可重入,不会在每次运行时创建新的一组:

Expand Down Expand Up @@ -145,7 +136,7 @@ bin/ti db execute-sql-statement \

SQL 默认通过 HTTPS SQL API 执行,一次命令只执行一个 statement。`--transport mysql` 是显式的一次性连接模式,不是隐藏 fallback。

## 4. 创建并管理 Filesystem
## 3. 创建并管理 Filesystem

创建一个由服务端分配稳定 ID 的资源。远端 inventory 是资源状态的权威来源,本地只保存按 ID 索引的访问凭证:

Expand All @@ -169,7 +160,7 @@ bin/ti fs check-file-system \

创建命令的 JSON 结果包含一次性的 `fs_token`。它是资源 owner credential,不能写入日志或公开传递。凭证存储在 `~/.ti/fs_credentials/<profile-key>/<file-system-id-key>/credentials`,不写入主 `~/.ti/credentials`。

## 5. 使用 Data Plane 操作文件
## 4. 使用 Data Plane 操作文件

```bash
bin/ti fs create-directory \
Expand Down Expand Up @@ -205,7 +196,7 @@ bin/ti fs ls --file-system-id "$FILE_SYSTEM_ID" --path /demo --output text
bin/ti fs cat --file-system-id "$FILE_SYSTEM_ID" --path /demo/from-data-plane.txt
```

## 6. 挂载并验证双向可见性
## 5. 挂载并验证双向可见性

```bash
export MOUNT_PATH="/tmp/ti-demo-${DEMO_ID}"
Expand Down Expand Up @@ -240,7 +231,7 @@ FUSE mount 可以在卸载前 drain dirty state。WebDAV 通过正常的 file cl
bin/ti fs drain-file-system --mount-path "$MOUNT_PATH"
```

## 7. 使用 Filesystem Git Workspace
## 6. 使用 Filesystem Git Workspace

在挂载目录内执行快速 clone 和 hydrate:

Expand Down Expand Up @@ -280,7 +271,7 @@ bin/ti fs-git remove-git-worktree \

`ti fs-git` 不替代 Git。它负责为 Filesystem mount 准备 clone、hydrate 和 worktree 工作流;普通提交和分支操作仍使用 `git`。

## 8. 使用 Journal 记录 Agent 工作流
## 7. 使用 Journal 记录 Agent 工作流

```bash
export JOURNAL_ID="jrn-demo-${DEMO_ID}"
Expand Down Expand Up @@ -317,7 +308,7 @@ bin/ti fs-journal verify-journal \

Journal 是 append-only、可验证的 workflow ledger,不是普通文本日志文件。

## 9. 使用 Vault 管理和委派 Secret
## 8. 使用 Vault 管理和委派 Secret

```bash
printf 'demo-token\n' > /tmp/ti-demo-token.txt
Expand Down Expand Up @@ -362,7 +353,7 @@ bin/ti fs-vault list-audit-events \

Vault mount 是只读 FUSE view,需要 delegated Vault token;Windows 不支持,macOS 需要 macFUSE。`run-with-secret` 可在不把值写进命令行的情况下将 secret 注入子进程。

## 10. 清理
## 9. 清理

FUSE mount 先 drain,再卸载。WebDAV mount 跳过 drain:

Expand Down
16 changes: 4 additions & 12 deletions docs/priciples.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ ti is currently in Preview. Its feature and command contracts can change before

## Product Scope

- `ti organization` reads TiDB Cloud organization and project context.
- `ti db` manages TiDB Cloud Starter clusters and branches, prepares SQL users, formats connection strings, and executes one SQL statement per invocation.
- `ti fs` manages TiDB Cloud Filesystem resources, files, layers, packs, and mounts.
- `ti fs-git`, `ti fs-journal`, and `ti fs-vault` expose Filesystem-backed Git workspace, append-only journal, and secret-management workflows.
Expand All @@ -23,7 +22,7 @@ The command tree has at most two command levels:
ti <command> [subcommand]
```

`configure` and `update` are intentional top-level verb exceptions. Other top-level commands identify product domains: `organization`, `db`, `fs`, `fs-git`, `fs-journal`, and `fs-vault`.
`configure` and `update` are intentional top-level verb exceptions. Other top-level commands identify product domains: `db`, `fs`, `fs-git`, `fs-journal`, and `fs-vault`.

- Commands and flags use complete, self-explanatory names.
- Flags are long-only. Do not add one-letter flags.
Expand Down Expand Up @@ -91,25 +90,19 @@ Environment credentials must not create or select a synthetic `[env]` profile. A

TiDB Cloud control-plane requests use HTTP Digest authentication. API keys must not be used as SQL Basic Auth credentials or Filesystem data-plane credentials.

## Configure And Default Project
## Configure

`ti configure` collects:

- a canonical `region_code`;
- a TiDB Cloud public API key;
- a TiDB Cloud private API key.

After validating the keys, configure lists accessible projects, requires exactly one project whose type is `tidbx_virtual`, and stores its ID as the profile's `project_id`. It commits the profile only after discovery succeeds.
Configure validates the local inputs and stores them atomically. It does not call TiDB Cloud, validate the keys remotely, discover projects, or persist a project ID. Authentication and authorization failures are reported by the first remote command that uses the keys.

`ti configure --non-interactive` reads flags first, then `TI_REGION_CODE`, `TIDB_CLOUD_PUBLIC_KEY`, and `TIDB_CLOUD_PRIVATE_KEY`, and fails instead of prompting for missing input. Interactive configure must handle Ctrl+C and exit with code 130.

Starter cluster creation resolves its project in this order:

1. Explicit non-empty `--project-id`.
2. The selected profile's discovered `project_id`.
3. Otherwise omit the project label and let TiDB Cloud select the account default.

Other DB operations identify existing resources by cluster or branch ID. Filesystem provisioning does not use the DB `project_id`.
Starter cluster creation always omits project selection and lets TiDB Cloud select its server-side default project. Project-related fields and labels returned by TiDB Cloud remain unchanged in command output. Other DB operations identify existing resources by cluster or branch ID.

## Local State And Credentials

Expand All @@ -128,7 +121,6 @@ Example:
# ~/.ti/config
[default]
region_code = "aws-us-east-1"
project_id = "..."

# ~/.ti/credentials
[default]
Expand Down
Loading