Skip to content

Align cluster tools with nested S3 storage access - #33

Merged
rmorehig merged 5 commits into
mainfrom
rafa/cluster-s3-api-contract
Oct 19, 2026
Merged

rmorehig merged 5 commits into
mainfrom
rafa/cluster-s3-api-contract

Conversation

@rmorehig

@rmorehig rmorehig commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Cluster tools now accept optional s3StorageAccess containing externalId and resourceTag, separate from s3Storage. The API owns default generation and persistence. MCP forwards only supplied overrides and returns the API's nested s3_storage_access response.

Custom cluster storage requires an External ID matching the IAM trust policy. Pre-creation verification accepts it under the same access object and saves nothing. Database creation/verification sends only s3_storage and reuses the cluster's saved identity. Strict schemas reject top-level identity fields, flat storage fields, and database overrides. Region selection and routing from current main are preserved across discovery, verification, and creation.

Tool input example

create-cluster (replica count and sizes must come from list-cluster-sizes):

{
  "organization": "acme",
  "name": "production",
  "replicas": 2,
  "minimumSize": {
    "cpuCores": 2,
    "memoryGiB": 8
  },
  "maximumSize": {
    "cpuCores": 2,
    "memoryGiB": 8
  },
  "s3StorageAccess": {
    "externalId": "rawtree-5b71c457-7d83-474b-9db9-6dc48a1ec042",
    "resourceTag": "rawtree-dc1fb78e-341d-48f8-a183-9ecea12eb41d"
  },
  "s3Storage": {
    "data": { "bucket": "acme-data" },
    "backups": { "bucket": "acme-backups" },
    "roleArn": "arn:aws:iam::123456789012:role/RawTreeS3"
  }
}

Omit s3StorageAccess and s3Storage for managed storage with API-generated identity. For custom storage, first call verify-cluster-s3-access with the same organization/region, s3StorageAccess.externalId, and s3Storage.

The API receives this storage portion of the creation body:

{
  "s3_storage_access": {
    "external_id": "rawtree-5b71c457-7d83-474b-9db9-6dc48a1ec042",
    "resource_tag": "rawtree-dc1fb78e-341d-48f8-a183-9ecea12eb41d"
  },
  "s3_storage": {
    "data": { "bucket": "acme-data", "path": "" },
    "backups": { "bucket": "acme-backups", "path": "" },
    "role_arn": "arn:aws:iam::123456789012:role/RawTreeS3"
  }
}

Relevant managed-storage response fields:

{
  "s3_storage_access": {
    "external_id": "rawtree-5b71c457-7d83-474b-9db9-6dc48a1ec042",
    "resource_tag": "rawtree-dc1fb78e-341d-48f8-a183-9ecea12eb41d"
  },
  "s3_storage": null
}

Compatibility and validation

Breaking contract coordinated with Platform #1482 and CLI #59. Existing tool names are unchanged. No client-side identity generation, release/version bump, is included. Platform #1482 pins this commit in its hosted MCP adapter.

  • pnpm test: 229 tests passed, including actual in-memory MCP transport, nested input serialization, API-default/error forwarding, strict legacy-input rejection, and region routing.
  • TypeScript build and Biome checks passed.
  • Live MCP create/get against the rebuilt candidate Platform API passed with omitted identities; nested API-generated values persisted unchanged, and the temporary cluster was deleted.
  • Full branch autoreview through P3 with thermo-nuclear criteria passed: autoreview --mode commit --commit <snapshot-parented-to-main> --max-priority P3.
  • Destination-shape update: all 229 tests, build, Biome, and autoreview --mode local --max-priority P3 with thermo-nuclear criteria passed. Nested missing/null/unknown destination fields are rejected before HTTP; omitted paths serialize to the bucket root.
  • Devin completed: stale description/example flags are addressed above. The nested identity contract is verified against the candidate Platform stack and requires coordinated deployment; this is not a deployed-production claim. CI is pending; no package is published.

@devin-ai-integration devin-ai-integration Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Newer findings are available below. Devin Review posted a newer report on this PR, in addition to the findings presented here.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

@devin-ai-integration devin-ai-integration Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Newer findings are available below. Devin Review posted a newer report on this PR, in addition to the findings presented here.

Devin Review found 1 new potential issue.

Devin Review

Comment thread src/client.ts
Comment on lines +505 to +507
...(s3StorageAccess === undefined
? {}
: { s3_storage_access: s3StorageAccessRequestBody(s3StorageAccess) }),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Confirm the cluster identity wire contract

The author description specifies top-level identity fields, but create-cluster sends s3_storage_access. Confirm the deployed Platform API accepts this shape before release.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

@rmorehig rmorehig changed the title Align cluster identity and S3 tools with the new Platform API Align cluster tools with nested S3 storage access Oct 19, 2026

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

Devin Review

Comment thread src/tools/common.ts
Comment on lines +17 to +19
export const s3StorageInput = z.strictObject({
data: s3StorageDestinationInput.describe('Destination for table data.'),
backups: s3StorageDestinationInput.describe('Destination for backups.'),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 PR examples retain obsolete storage fields

The PR description still shows flat bucket fields. s3StorageInput rejects that tool example, while the API-body example differs from s3StorageRequestBody; rollout guidance needs updating.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

@rmorehig
rmorehig merged commit f5a3ff7 into main Oct 19, 2026
3 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.

1 participant