Skip to content

fix: cost-allocation tag activation is backfillable; the stamp is not - #212

Merged
stxkxs merged 1 commit into
mainfrom
cost-tag-backfill
Aug 8, 2026
Merged

fix: cost-allocation tag activation is backfillable; the stamp is not#212
stxkxs merged 1 commit into
mainfrom
cost-tag-backfill

Conversation

@stxkxs

@stxkxs stxkxs commented Aug 8, 2026

Copy link
Copy Markdown
Member

The claim

Four places in cost-pipeline state that activating a cost-allocation tag is irreversible:

  • README.md:96 — heading: "activation is not retroactive"
  • README.md:111-113 — "Every hour before activation is permanently NULL for that key. There is no backfill."
  • main.tf:776 — "Activation is not retroactive, so nothing before it is ever attributed."
  • main.tf:1202 — "Spend inside that window is unattributable permanently"

And check-doc-contracts.sh required the README to contain the string not retroactive, so the claim wasn't just written down — it was held in place by a gate.

It's wrong

AWS ships cost allocation tag backfill: a management account can request up to twelve months, and it updates Cost Explorer, Data Exports and the CUR automatically on their next 24h refresh. One request at a time, one per 24 hours.

Reachable today in this account:

$ aws ce list-cost-allocation-tag-backfill-history
{ "BackfillRequests": [] }

What is actually irreversible

Backfill applies the tags' current activation status across history. It does not invent tag values. AWS states the constraint directly:

The resource tag must be historically assigned to the AWS Resource for the backfilled cost data to be available.

So the advice these docs give is right and the reason is not — and the difference decides what you hurry:

recoverable? cost of missing it
activating the key late yes one backfill request
resource ran untagged no that spend, permanently

Which is exactly why this component stamps PlatformId on its own buckets at install rather than waiting for the first tenant. That behaviour doesn't change; its justification becomes true.

The gate

A gate whose pass condition is a false statement would have rejected this correction. It now requires the README to say which half is recoverable.

Proven red by removing every occurrence of the word from the README and watching it fail, then green on restore. Worth recording that the first attempt at that proof was itself broken — the placeholder still contained the substring the check greps for case-insensitively, so the gate passed and looked vacuous when the test was the thing at fault.

Four places in cost-pipeline state that activating a cost-allocation tag is
irreversible — "It is not retroactive… There is no backfill", "nothing before it
is ever attributed", "Spend inside that window is unattributable permanently".
A doc-contract check enforced that wording, so the claim was not merely written
down, it was held in place.

It is wrong. AWS ships cost-allocation tag backfill: a management account can
request up to twelve months, and it updates Cost Explorer, Data Exports and the
CUR automatically on their next 24h refresh. One request at a time, one per 24
hours. The API is reachable today —
`aws ce list-cost-allocation-tag-backfill-history` returns an empty request
list rather than an error.

What backfill genuinely cannot do is invent tag values. AWS states the
constraint directly: "the resource tag must be historically assigned to the AWS
Resource for the backfilled cost data to be available." Backfill applies the
tags' current activation status across history; a resource that ran untagged
stays unattributable no matter when the switch is flipped.

So the advice these documents give is right and the reason they give is not, and
the difference decides what you hurry. The switch is repairable at the cost of a
backfill request. The stamp is the irreversible half, which is why this component
tags its own buckets at install rather than waiting for the first tenant.

──────────────────────── the gate ────────────────────────

check-doc-contracts.sh required the README to contain the string "not
retroactive" — a gate whose pass condition was a false statement, and which would
have rejected this correction. It now requires the README to say which half is
recoverable, and its explanation carries the distinction rather than restating
the error.

Proven red by removing every occurrence of the word from the README and watching
it fail, then green on restore. The first attempt at that proof was itself
broken: the placeholder still contained the substring the check greps for
case-insensitively, so the gate passed and looked vacuous when the test was the
thing at fault.
@stxkxs
stxkxs merged commit 90c9bd4 into main Aug 8, 2026
41 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