Skip to content

docs: propose the S3 object-tagging design (VersionState second tenant) - #80

Merged
frrist merged 1 commit into
frrist/feat/object-lockfrom
design/s3-object-tagging
Aug 14, 2026
Merged

docs: propose the S3 object-tagging design (VersionState second tenant)#80
frrist merged 1 commit into
frrist/feat/object-lockfrom
design/s3-object-tagging

Conversation

@frrist

@frrist frrist commented Aug 13, 2026

Copy link
Copy Markdown
Member

Design doc for S3 object tagging, following the doc-then-impl stack workflow — stacked on #78 (the object-lock implementation), because tagging is the second tenant of the version-state tree that design built. Rebases down the stack as #77/#78 land.

Tagging rides the lock design's format exactly as planned: the Tags field is already reserved on VersionState, so this is handlers and conformance rows with no format change. The spec pins the three deltas from lock:

  • No bucket gate — tags work on any bucket, unversioned included; the check order is the lock order minus the lock-enabled step, and tags on unversioned buckets make the write-rule discard cleanup live for real.
  • Absent state is a success — a version without tags answers an empty tag set (200), where lock answers a 400 sentinel.
  • A true unset existsDeleteObjectTagging is what the state tree's empty-block elision rule was written for.

Creation-time stamping covers the x-amz-tagging header on PUT (parsed backend-side via backend.ParseObjectTags, before ingest), the copy tagging directive (controller-defaulted to COPY: inherit the resolved source version's tags; REPLACE takes the header), and the multipart session carry. GET/HEAD gain the x-amz-tagging-count echo from the same state-block fetch as the lock headers.

Implementation follows as the stacked PR from frrist/feat/object-tagging.

🤖 Generated with Claude Code

@frrist frrist self-assigned this Aug 13, 2026

@hannahhoward hannahhoward left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

My eyes are glazing a bit, but this looks simple enough. LGTM

Object tagging rides the version-state tree the object-lock design
built: the Tags field is already reserved on VersionState, so tagging is
handlers and conformance rows with no format change. The spec pins the
three deltas from lock: no bucket gate (the check order drops the
lock-enabled step, and tags on unversioned buckets make the write-rule
discard cleanup live), absent state is a success (empty tag set, not a
sentinel), and DeleteObjectTagging is the true unset the empty-block
elision rule exists for. Creation-time stamping covers the x-amz-tagging
header on PUT (parsed backend-side via backend.ParseObjectTags), the
copy tagging directive (controller-defaulted to COPY), and the multipart
session carry; GET/HEAD gain the tag-count echo.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@frrist
frrist force-pushed the design/s3-object-tagging branch from 4e3b30f to b6c9581 Compare August 14, 2026 00:56
@frrist
frrist merged commit 5e0718e into main Aug 14, 2026
14 of 24 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.

2 participants