π¦«ποΈ dispatch to foreman
π§ task enqueued
ββ priority = ?
ββ yieldage = ?
ββ leverage = ?
title
seed(rule): classify every declared attribute β unique / readonly / mutable / immutable
description
.what
a declared resource has attributes, and each one belongs to exactly one drift class. today that
classification lives nowhere: it is re-derived per resource, recorded in a jsdoc if at all, and the
recorded ones are found only by a reader who already opened that file.
the ask: a rule that requires every attribute be classified explicitly β and a vocabulary of
four classes to classify it into.
.the four classes
| class |
on drift |
example in this repo |
| unique |
identity β a different resource |
DeclaredAwsSsmParameterPlain.name |
| readonly |
aws assigns it; never compared |
an aws-assigned version, timestamp |
| mutable |
reconcile in place |
DeclaredAwsEc2Instance.sourceDestChecked |
| immutable |
fail loud; the operator recreates |
DeclaredAwsEc2Instance.subnet, template, securityGroups |
β οΈ a fifth was found and has no precedent: immutable + un-recreatable β where the api exposes no
converge call AND a delete is barred, so there is no remedy but a rename of the declaration. it
belongs in the vocabulary even though this repo does not ship one today.
.why β the trap is that a class is not readable off the object
the object shape carries unique and readonly as statics. it carries no marker for the other
two. so mutable and immutable are indistinguishable at a glance, and an author classifies by
intuition β which is wrong in both directions:
- an attribute that reads immutable and is mutable β a drift dead-ends the apply that should
have healed it
- an attribute that reads ordinary and is immutable β a drift routes to UPDATE, and the write is
either rejected by the api or lands somewhere it should not
.the three occurrences β two already in one file, one from a parked vision
rule.prefer.wet-over-dry sets the bar at three.
1. sourceDestCheck β reads immutable, is mutable. getEc2InstanceImmutableDrift.ts:6-11:
.why = an EC2 instance cannot change its launch template, subnet, security groups,
or public-ip association in place β those require a terminate + recreate. but
`sourceDestCheck` IS mutable (ModifyInstanceAttribute changes it on a live
instance), so a drift on it must reconcile in place, NOT dead-end the apply.
2. metadataOptions β a scope boundary, tracked at a different layer. same file, lines 17-28:
the attribute is deliberately absent from the compare because the posture lives at the template
layer, and the note exists so a reader does not assume plan proves a live instance posture. that
is a classification decision with real safety weight, recorded in a jsdoc.
3. documentType on an SSM document β the un-recreatable fifth class. from the parked
v2026_09_04.feat-ssm-document vision. UpdateDocumentRequest carries no DocumentType field at
all, so aws exposes no converge call; and a recreate needs a delete, which is barred against a
document another party owns. the vision had to invent the category to describe it.
β occurrences 1 and 2 sit in the SAME file, and 3 was derived from scratch with no reason to
open it. that is the argument in one line: a jsdoc reaches that file, and a rule reaches everyone.
.what the rule would require
- every attribute on a
DeclaredAwsX is classified explicitly, into one of the five
- the classification is discoverable without a read of the drift op β a static, a jsdoc block
on the object, or a table; the shape is the open question
- an attribute whose class is surprising (mutable but reads immutable, or the reverse) carries
the reason, since that is the case a future author will get wrong
- immutable + un-recreatable carries the remedy explicitly, because there is no obvious one
.the open question, left open on purpose
where does the classification live? a fifth static on the domain object is the tidiest and it is
a change to every extant resource. a jsdoc convention is cheap and stays unenforceable. that trade
belongs to whoever picks this up.
.the transferable shape
a taxonomy that lives in a comment reaches one file; a taxonomy that lives in a rule reaches
every author. where a category is re-derived per instance, it will be derived wrong at least
once β and the wrong derivation is invisible, because the artifact looks complete either way.
.where this came from
v2026_09_04.feat-ssm-document, .what is awkward #6. the vision itself was parked (see #94); this
finding is repo-level and outlives it.
seeded by human + beaver π¦«
π¦«ποΈ dispatch to foreman
title
seed(rule): classify every declared attribute β unique / readonly / mutable / immutable
description
.what
a declared resource has attributes, and each one belongs to exactly one drift class. today that
classification lives nowhere: it is re-derived per resource, recorded in a jsdoc if at all, and the
recorded ones are found only by a reader who already opened that file.
the ask: a rule that requires every attribute be classified explicitly β and a vocabulary of
four classes to classify it into.
.the four classes
DeclaredAwsSsmParameterPlain.nameDeclaredAwsEc2Instance.sourceDestCheckedDeclaredAwsEc2Instance.subnet,template,securityGroupsconverge call AND a delete is barred, so there is no remedy but a rename of the declaration. it
belongs in the vocabulary even though this repo does not ship one today.
.why β the trap is that a class is not readable off the object
the object shape carries
uniqueandreadonlyas statics. it carries no marker for the othertwo. so mutable and immutable are indistinguishable at a glance, and an author classifies by
intuition β which is wrong in both directions:
have healed it
either rejected by the api or lands somewhere it should not
.the three occurrences β two already in one file, one from a parked vision
rule.prefer.wet-over-drysets the bar at three.1.
sourceDestCheckβ reads immutable, is mutable.getEc2InstanceImmutableDrift.ts:6-11:2.
metadataOptionsβ a scope boundary, tracked at a different layer. same file, lines 17-28:the attribute is deliberately absent from the compare because the posture lives at the template
layer, and the note exists so a reader does not assume
planproves a live instance posture. thatis a classification decision with real safety weight, recorded in a jsdoc.
3.
documentTypeon an SSM document β the un-recreatable fifth class. from the parkedv2026_09_04.feat-ssm-documentvision.UpdateDocumentRequestcarries noDocumentTypefield atall, so aws exposes no converge call; and a recreate needs a delete, which is barred against a
document another party owns. the vision had to invent the category to describe it.
β occurrences 1 and 2 sit in the SAME file, and 3 was derived from scratch with no reason to
open it. that is the argument in one line: a jsdoc reaches that file, and a rule reaches everyone.
.what the rule would require
DeclaredAwsXis classified explicitly, into one of the fiveon the object, or a table; the shape is the open question
the reason, since that is the case a future author will get wrong
.the open question, left open on purpose
where does the classification live? a fifth static on the domain object is the tidiest and it is
a change to every extant resource. a jsdoc convention is cheap and stays unenforceable. that trade
belongs to whoever picks this up.
.the transferable shape
.where this came from
v2026_09_04.feat-ssm-document,.what is awkward#6. the vision itself was parked (see #94); thisfinding is repo-level and outlives it.
seeded by human + beaver π¦«