Increase artifact content size limit from 5 MiB to 10 MiB

Doubles the maximum UTF-8 bytes accepted for manually shared artifacts,
enabling users to share larger content while maintaining recovery and
transport constraints.
This commit is contained in:
Jinjing
2026-09-01 02:31:28 -07:00
parent 28373fcea7
commit 0824074916
7 changed files with 17 additions and 12 deletions
@@ -274,9 +274,12 @@ describe('artifact create intent store', () => {
).toThrow(/unsupported format/)
})
it('persists a 5 MiB escaped artifact within the recovery limit', async () => {
it('persists an escaped artifact within the recovery limit', async () => {
const userDataPath = await createUserDataPath()
const nearLimitBody = { ...body, content: '"'.repeat(ARTIFACT_MAX_CONTENT_BYTES) }
const nearLimitBody = {
...body,
content: '"'.repeat(Math.floor(ARTIFACT_MAX_CONTENT_BYTES / 2))
}
expect(
artifactWriteRequestByteLength({ sourceKey: '/repo/report.html', ...nearLimitBody })
).toBeLessThanOrEqual(ARTIFACT_MAX_REQUEST_BYTES)
@@ -307,7 +310,7 @@ describe('artifact create intent store', () => {
'key-a',
{ ...body, content: 'x'.repeat(ARTIFACT_MAX_CONTENT_BYTES + 1) }
)
).toThrow(/5 MiB limit/)
).toThrow(/10 MiB limit/)
})
it('rejects a recovery body whose escaped request exceeds the transport budget', async () => {
@@ -207,7 +207,7 @@ export function getOrCreateArtifactCreateIntent(
body: ArtifactWriteBody
): ArtifactCreateIntent {
if (artifactContentByteLength(body.content) > ARTIFACT_MAX_CONTENT_BYTES) {
throw new Error('Artifact content exceeds the 5 MiB limit.')
throw new Error('Artifact content exceeds the 10 MiB limit.')
}
if (artifactIntentRequestByteLength(sourceKey, body) > ARTIFACT_MAX_REQUEST_BYTES) {
throw new Error('Artifact create recovery record exceeds the supported size.')
@@ -46,7 +46,7 @@ describe('artifact RPC schemas', () => {
).toBe(false)
})
it('accepts a 5 MiB UTF-8 artifact at the content boundary', () => {
it('accepts a 10 MiB UTF-8 artifact at the content boundary', () => {
expect(
writeSchema('artifacts.publish').safeParse({
...validRequest,
@@ -56,7 +56,9 @@ describe('artifact RPC schemas', () => {
})
it('measures the content boundary in UTF-8 bytes', () => {
const exact = `${'€'.repeat(Math.floor(ARTIFACT_MAX_CONTENT_BYTES / 3))}aa`
const euroCount = Math.floor(ARTIFACT_MAX_CONTENT_BYTES / 3)
const asciiBytes = ARTIFACT_MAX_CONTENT_BYTES - euroCount * 3
const exact = `${'€'.repeat(euroCount)}${'a'.repeat(asciiBytes)}`
const oversized = `${exact}€`
expect(new TextEncoder().encode(exact).byteLength).toBe(ARTIFACT_MAX_CONTENT_BYTES)
expect(new TextEncoder().encode(oversized).byteLength).toBeGreaterThan(
@@ -70,11 +72,11 @@ describe('artifact RPC schemas', () => {
).toBe(false)
})
it('allows JSON escaping within the bounded 5 MiB content request', () => {
it('allows JSON escaping within the bounded content request', () => {
expect(
writeSchema('artifacts.publish').safeParse({
...validRequest,
content: '"'.repeat(ARTIFACT_MAX_CONTENT_BYTES)
content: '"'.repeat(Math.floor(ARTIFACT_MAX_CONTENT_BYTES / 2))
}).success
).toBe(true)
})
+1 -1
View File
@@ -30,7 +30,7 @@ const WriteRequest = z
.min(1)
.max(ARTIFACT_MAX_CONTENT_BYTES)
.refine((content) => artifactContentByteLength(content) <= ARTIFACT_MAX_CONTENT_BYTES, {
message: 'Artifact content exceeds the 5 MiB limit.'
message: 'Artifact content exceeds the 10 MiB limit.'
}),
contentType: z.enum(['text/html', 'text/markdown']),
fileName: z.string().min(1).max(512),
@@ -101,7 +101,7 @@ describe('artifact publish flow', () => {
})
})
it('publishes content at the 5 MiB boundary', async () => {
it('publishes content at the 10 MiB boundary', async () => {
mocks.callRuntimeRpc.mockResolvedValue({ status: 'ok', value: published })
const createRequest = vi.fn().mockResolvedValue({
...request,
@@ -64,7 +64,7 @@ describe('browser artifact upload', () => {
} satisfies Partial<ArtifactPublishPreparationError>)
})
it('accepts a file whose stat is exactly at the 5 MiB boundary', async () => {
it('accepts a file whose stat is exactly at the 10 MiB boundary', async () => {
stat.mockResolvedValueOnce({
size: ARTIFACT_MAX_CONTENT_BYTES,
isDirectory: false,
+1 -1
View File
@@ -1,5 +1,5 @@
/** Maximum UTF-8 bytes accepted for a manually shared artifact. */
export const ARTIFACT_MAX_CONTENT_BYTES = 5 * 1024 * 1024
export const ARTIFACT_MAX_CONTENT_BYTES = 10 * 1024 * 1024
/** Legacy CLI/SSH envelope cap; those transports still have ~1 MiB control frames. */
export const ARTIFACT_CLI_MAX_RPC_BYTES = 800 * 1024