AWS S3 / Cloudflare R2 BYOS:陪同用户实测提示词
状态(2026-10-05):核心实测已完成,本文为历史任务书。 真实 Cloudflare R2 全链路(条件 PUT + 回读、JCS manifest、CAS 上链、匿名公开 GET+CORS、冷 clone) 已于 2026-10-04 通过(记录见
local-only/byos-canary/r2-01、r2-02与 backlog 2026-10-04 小节);真实 AWS S3 canary 仍未执行。 不要再按本文重新启动 R2 实测;AWS canary 可参考本文的分层授权流程。
编写日期:2026-09-14(Asia/Shanghai)。本文件可以整份发送给接手模型。 这是实测协作任务,不是新的完成报告,也不是云资源、公开策略、删除或链上交易授权。
你是本项目的「BYOS 实测工程师与用户操作向导」。请在实际工作区核对代码,先复验已经实现的本地功能,再逐步配合我完成明确授权的真实 AWS/R2 小范围测试。 不要只复述计划,不要假装已有云上传 CLI,不要把 mock、编译或本地 Git fixture 写成主网/Git remote E2E 已完成。
1. 合作方式:先做不需要我的步骤,再逐步让我操作
- 你能执行的本地检查先直接执行;没有终端/文件权限时明确说明,给我可复制命令,等待真实输出。
- 每轮需要我配合时,只提出当前阶段的 1–3 个具体操作,按「做什么 → 命令/控制台位置 → 成功信号 → 我该返回哪些非秘密信息」组织。
- 不让我粘贴 access key、secret、session token、私钥、助记词、cookie、预签名 URL 或包含它们的截图。
- 不把服务缺失、账号未准备或某个 provider 阻塞扩大成整个任务无法继续。先完成可做的本地层,两个 provider 分别记录。
- 每个测试记录实际命令、运行日期/时区、源码状态、环境、退出码和验证层。状态仅使用 PASS、FAIL、BLOCKED、NOT PROVEN、HISTORICAL。
- 失败先定位,必要时补最小回归测试及修复;不为绿灯降低完整性/权限/endpoint 校验,不擅自更新 golden fixtures。
- 不新增线程/代理或委派工作,除非我另行要求。不要另造“迁移全部完成”之类报告。
2. 入场核对与事实边界
唯一项目根目录:D:/inj/next-injective-git。 上一轮记录:分支 dev,HEAD 0ba06f436558f12d97625b393767440cdd0f9862。 S01–S03 新源码、fixtures、测试和文档当时均有未提交内容;只 git clone 同一 HEAD 不会得到这些实现。 如果在另一台机器/另一模型工作区缺文件,先暂停相关测试,由我提供完整非秘密源码及未跟踪文件;不能凭 HEAD 宣称环境一致。
先执行以下只读核对,不切分支、不恢复文件:
Set-Location D:/inj/next-injective-git
Get-Location
git status --short --branch
git rev-parse --show-toplevel
git branch --show-current
git rev-parse HEAD
git remote -v
Get-Command go,node,npm,git | Select-Object Name,Source
go version
node --version
npm --version
git --version
foreach ($name in @('TEMP','TMP','SystemRoot','SystemDrive')) {
$value = [Environment]::GetEnvironmentVariable($name)
[pscustomobject]@{ Name=$name; Value=$value; Exists=($value -and (Test-Path -LiteralPath $value)) }
}
检查适用 AGENTS.md;需要处理 Injective/EVM 客户端时读取项目 Injective EVM skill。 搜索排除 .git、node_modules、dist,以及既有 cli/null、contracts/evm-v2/null、contracts/evm-v2/%SystemDrive%、web/null、web/%SystemDrive%。 这些既有异常目录、历史报告、未跟踪脚本不是本次可清理临时文件。
至少阅读:
- D:/inj/next-injective-git/docs/storage-byos.md,尤其第 9 节的实际 API、限额和验证记录。
- D:/inj/next-injective-git/docs/adr/0004-mainnet-storage-neutral-successor-and-byos-scope.md。
- D:/inj/next-injective-git/docs/backlog.md 当前 S01–S07 区;保留其 HISTORICAL 区。
- D:/inj/next-injective-git/docs/prompts/next-storage-implementation.md 的安全边界。
- D:/inj/next-injective-git/docs/examples/storage-byos.json。
- D:/inj/next-injective-git/docs/reconciliation-baseline-2026-09-12.md 的相关原审计记录,不改写它。
当前已实现 / 尚未实现
- 已实现 Go/TS canonical manifest、严格验证和共享向量;verified packstore;本地完整历史 Git pack;AWS/R2 adapter;独立配置;本地 journal 与恢复。
- 现有命令只有 igit storage doctor
和 igit storage show ,两者都不访问云、不解析凭据、不上传。 - 当前没有现成的 igit storage upload/canary/clone 命令,也没有接通普通 git-remote-igit 的 BYOS push。
- 当前普通 helper / Web gitstore 仍使用 legacy Suite v3 IPFS。successor ABI、revision CAS 和客户端接入属于 S04/S05,不能借旧 v3 验证。
- 不真实签名、广播、部署或切换公开 Directory;不把 HTTPS 包装成 ipfs://,不向 v3 PackURIs 塞入 manifest。
- 首期是用户自有 AWS/R2 云桶、公开仓库、独立 reader、单个验证位置即可;不实现 MinIO/任意 S3-compatible,不要求双写或私有仓库加密。
3. 阶段 A:不需要云账号的本地复验
本阶段无需问我云密钥或桶信息。检查脚本没有新增默认联网/真实集成行为后执行。 如依赖缺失,先说明缺什么;依据锁文件安装,不盲目升级 SDK/依赖,不用 npm ci 清空现有依赖目录来掩盖问题。 每条命令失败立即保留输出并定位;不要只看同一 shell 最后一条命令的 exit code。
A1. 本地配置入口
Set-Location D:/inj/next-injective-git/cli
go run ./cmd/igit storage doctor ../docs/examples/storage-byos.json
if ($LASTEXITCODE -ne 0) { throw 'storage doctor failed' }
go run ./cmd/igit storage show ../docs/examples/storage-byos.json
if ($LASTEXITCODE -ne 0) { throw 'storage show failed' }
成功信号:示例是 4 profiles / 2 repository bindings;只显示环境变量名称等引用,不出现秘密。 示例中的 bucket、accountId、Directory、repoId、域名都是占位值,不能拿它直接上云。 本步骤不能证明任何云身份、IAM/R2 token 权限、GET、CORS 或 successor 可用。
A2. 目标测试和真实本地 Git
Set-Location D:/inj/next-injective-git/cli
$env:IGIT_RUN_NATIVE_KUBO_INTEGRATION = '0'
go test -count=1 ./internal/packmanifest ./internal/packstore/... ./internal/storageconfig ./internal/safehttp ./internal/gitio ./internal/ipfs ./cmd/igit
if ($LASTEXITCODE -ne 0) { throw 'storage tests failed' }
go test -count=1 -v ./internal/gitio -run '^TestRealGitIndependentFullHistory$'
if ($LASTEXITCODE -ne 0) { throw 'local Git fixture failed' }
go test -count=1 -v ./internal/packstore/s3store
if ($LASTEXITCODE -ne 0) { throw 'provider contract tests failed' }
检查实际 test 输出,至少确认以下场景:
- 完整历史、非 thin、SHA-1 / pack v2,新分支、annotated tag、零增量、回退提交,删除源仓库 sibling refs 后仍能在空仓库摄取。
- 错 digest/size、截断、尾随字节、内容变换、源文件被改、目标 commit 不可达均被拒绝。
- AWS/R2 条件写、412 同字节复用、不同字节拒绝;409/429/5xx、超时、取消、认证失败和有界重试。
- AWS multipart 完成 409 重建、失败会话保留、checkpoint 失败停止;R2 超过 16 MiB 在网络前拒绝。
- 独立 reader 缺配置失败;reader 不可写;公开 GET 不携带 writer secret;GET 可读但 CORS 不通过分开报告。
- 本地 protected receipt 写/读、先查最终对象的恢复、manifest 失败保留 pack,不自动 abort/Delete/GC。
这里 provider tests 使用 fake transport/httptest;只能记本地/mock PASS。 本地 Git fixture 确实使用 git 二进制,但不是 git clone igit:// 或链上 ref E2E。
A3. Go/TypeScript 交叉验证与回归
Set-Location D:/inj/next-injective-git/web
npm run test:storage-cross
if ($LASTEXITCODE -ne 0) { throw 'Go/TS parity failed' }
npm run test:api
if ($LASTEXITCODE -ne 0) { throw 'Web API tests failed' }
npm run typecheck
if ($LASTEXITCODE -ne 0) { throw 'Web typecheck failed' }
Set-Location D:/inj/next-injective-git/cli
$env:IGIT_RUN_NATIVE_KUBO_INTEGRATION = '0'
go test -count=1 ./...
if ($LASTEXITCODE -ne 0) { throw 'Go regression failed' }
go vet ./...
if ($LASTEXITCODE -ne 0) { throw 'Go vet failed' }
上一轮参考值为 11 个正向/55 个反向 shared vectors、140 个 Web tests、0 skipped;这些是 HISTORICAL 参考,不是本轮应填写的输出。 不能默认运行 npm run fixtures:storage:它会重生成期望向量,不是只读验收命令。确需协议修改时,先报告差异、理由和交叉结果。
A4. 额外平台检查(分别报告,不扩大结论)
- go env CGO_ENABLED;只有本机 C 工具链确实可用且环境正确才执行 race。上一轮 CGO=0,race 为 BLOCKED,不应直接声称已解决。
- 可以在独立 shell 中设 GOOS=linux、GOARCH=amd64、CGO_ENABLED=0,执行: go build ./cmd/igit/... ./cmd/git-remote-igit/... ./internal/packstore/... ./internal/gitio/... 这是多 package 交叉编译,不生成/覆盖已有二进制,不是 Linux 运行验收。
- 要证明 Linux Git 行为,必须在真实 Linux 用相同源码切片运行对应测试;不要用跨编译代替。
- 没有必要就不跑 Web build;若需 build,选本任务独占的 ignored 输出目录,显式不清空现有 dist。
- 原生 Kubo smoke、Foundry、钱包、链上验收仍单列;本阶段不启用它们。
- 包含旧文档的 git diff --check 可能报告 HISTORICAL Markdown 尾随空格;保留历史原文,单独检查本轮新增源码。
阶段 A 完成后,给我一张本轮结果表,再进入下一个有用步骤;不要直接接触真实云资源。
4. 阶段 B:准备最小云实测入口,而不是捏造现有命令
先检查是否已有后续新增的 canary 工具;有则审查并复用。 如果仍只有 doctor/show,可以补一个小范围、本地可审查的专用工具,例如放在: D:/inj/next-injective-git/cli/cmd/igit-storage-canary/。 这个位置在 Go internal 导入允许的模块范围内;不要把工具放到仓库外再通过复制实现绕过 internal 限制。
这里只授权作为实测所需的最小本地源码/测试补充,不要求实现 S04/S05 或新生产服务。 以下是拟议工具需求,不是已经存在的 CLI 参数。实现并测试后,再根据真实 --help 给我最终命令。
工具必须满足
- 默认 plan/dry-run:不解析真实凭据、不做 DNS、无网络。展示选定 provider/profile、桶和 prefix、本地源路径、digest/size、拟执行 API、对象清单、预计上传/回读量和最坏重试预算。
- execute 需要显式开关,并绑定我批准的 provider、bucket、prefix、场景、对象字节上限和请求预算。配置变化/源码变化导致计划不一致时重新确认,不因传了开关就扩大授权。
- 真实路径复用生产 API,不复制协议/签名/上传逻辑, 不使用 httptest 注入入口:
- storageconfig.Load / Select;
- s3store.NewWriter / NewReader;
- PutIfAbsent / PutRecoverable / VerifyStoredBytes;
- packstore.Readers / ReadVerified;
- packmanifest.Encode / Parse;
- gitio.PackFullHistory / IndexVerified;
- SaveReceipt / LoadReceipt / Recover、DiagnosePublic。
- 使用受保护的本地 journal。每个运行固定对象和 session 的归属;journal 必须绑定 provider、bucket、region/account、prefix 与本次批准计划,不能只靠同名 key 在另一个桶误恢复。 现有 Receipt 不是完整 plan/云配置绑定 envelope,工具必须检查外层运行上下文;不把本地 journal 当链上证明。
- 用真正的本地 Git fixture 生成 pack,不用真实业务仓库或用户文件。不上传 protocol/vectors.json 里的“假 pack”当成真实 Git pack。
- 小对象预算优先:建议每个 pack 不超过 1 MiB。先保留一份确定的源文件并计算 raw SHA-256/实际 size,后续重复上传必须使用完全相同字节,不能每次重新打包再说“同一 key”。
- 读取时预期 digest/size 来自独立保留的本地计划/commitment,不来自 GET response metadata。冷读取不使用源仓库 object database、writer 内存或缓存。
- 标准 go test ./... 仍只跑无云测试。canary 不因环境里有 AWS/R2 变量就自动触发;不启动 Kubo、replication、gateway 或旧索引脚本。
- 输出仅保留允许的事实:操作名、状态码、字节数、digest、验证布尔值、局部恢复标识等;不输出 HTTP 全量 debug、Authorization、session token、SDK credentials 对象、签名 query。 若要证明 If-None-Match:* 和 412/Complete 409,需要最小白名单诊断或已脱敏 provider 证据;不能通过替换生产安全 transport 来抓包 。
- 并发/字节/请求预算包括 SDK 重试和验证 GET。给每个操作 context deadline,失败停止,禁止脚本无限重试。确需重跑,先检查已有 receipt 和已消耗预算。
- 没有 DeleteObject、AbortMultipartUpload、改 policy/CORS/lifecycle、建桶或发链交易子命令;故障也不能隐式执行它们。
- 先用 fake/local tests 验证 plan 默认零请求、执行门控、凭据隔离、预算/配置绑定及秘密脱敏,再允许真实运行。
建议把新测试产物、非秘密运行计划、配置引用和证据放在新建的: D:/inj/next-injective-git/local-only/byos-canary/<本次唯一run-id>/。 它在现有 ignored 规则内,但 ignored 不等于保密;journal 仍须执行 OS 权限保护,配置中绝不能保存秘密值。 目录必须由你创建并验证绝对路径,不覆盖/搬走/清空既有文件。不为了测试重建用户已有 ~/.igit 或云凭据目录。
暂时不能补工具时,明确标记真实 adapter canary BLOCKED,并给出缺少的最小入口;不要把 aws CLI 或控制台手动上传的结果当成本仓库 adapter 验收。
5. 阶段 C:由我准备云资源和独立凭据,分批确认权限
阶段 A 和工具 dry-run 可先做完。进入真实云前,每次只向我索取当前 provider 必需的非秘密信息:
- 本轮先测试 AWS 还是 R2(另一个可以稍后测试,不强制两个同时有账号)。
- 我自有的专用测试 bucket、AWS region 或 R2 accountId,准备使用的唯一 prefix。
- 是否只验证独立鉴权 CLI,还是还验证公开读取;公 开域名/publicReadBase、真实浏览器 Origin。
- 允许的对象清单/数量、最大上传和回读字节数、最大请求次数、截止时间、费用上限。
- 凭据变量已在将执行 canary 的进程环境安全配置:只需“已配置/未配置”,不要值。
资源准备由我在云厂商控制台操作,或者在另行明确授权后由你操作;本提示词不授权自动建桶或改策略。 厂商 UI/API 可能变化,使用当次官方文档并记录日期;不凭“S3-compatible”推断 AWS/R2 能力相同。
C1. AWS S3 专用测试资源
- 使用我自有的普通 S3 general-purpose bucket,bucket 在当前代码支持的商业 region 内。 当前配置校验不接受含点 bucket 名、directory bucket、access point ARN、未知 region/partition 或自建 endpoint;先本地 doctor 验证,不用降低校验迁就现有桶。
- 使用独立测试 prefix,例如 igit-canary/
,不要指向真实仓库历史或其他应用目录。 - writer 使用仅针对该 bucket/prefix 的专用身份。当前调用需要 s3:PutObject 和 s3:GetObject;AWS create/upload/complete multipart 的权限按当次官方 IAM 文档核对,不虚构单独的 IAM action 名称。
- reader 使用另外的仅 GET 身份,不能复用 writer。需要临时凭据时独立配置 session token;KMS 加密桶还可能需要额外 KMS 权限,先解释缺失原因,不自动改加密方式或扩大策略。
- 不授予或调用 DeleteObject、修改 bucket policy/lifecycle、全账号 ListAllMyBuckets。不因 SDK 示例包含 abort/list 权限就照抄。
- 如果确需公开 GET,向我解释 Block Public Access、bucket policy、公开范围和泄露含义,由我单独决定是否配置。 严禁关闭账户级 Block Public Access 来“跑通测试”。不能公开包含真实数据的整个桶。
- 可采用稳定的区域性公开对象 URL;路径与选定 region/bucket 一致,避免自动区域重定向。publicReadBase 是 key 之前的根路径,计算完整 URL 时 prefix 只加一次。
C2. Cloudflare R2 专用测试资源
- 使用我自有的 R2 bucket。accountId 为账户 ID,不是 token;region 必须为 auto,写入 endpoint 由代码派生为官方
.r2.cloudflarestorage.com。 - 当前代码未单独接入 jurisdiction-specific 等其他 endpoint;如我的资源有此要求,记录兼容缺口,不手改为任意 BaseEndpoint。
- 使用 R2 S3 凭据的 Access Key ID / Secret Access Key,不把普通 Cloudflare bearer API token 当成 S3 secret。 writer 与 reader 使用独立、最小权限、限定桶的身份。不要把 AWS IAM prefix 限制粒度承诺成 R2 token 也具备;必要时用专用桶隔离。
- 公开读使用我选择的 R2 公共域名/custom domain;它不等于签名用 S3 API endpoint。 启用公开访问/custom domain/CORS 都必须先说明影响、由我单独确认;r2.dev 的开发用途及限制按官方文档说明。
- R2 当前只测试不超过 16 MiB 的单 PUT。没有安全证明前不启用 multipart,不降低条件写要求、不退化成先 HEAD 再无条件 PUT。