* feat(prod): add seahaven-prod DynamoDB CMK and site-alerts alarm-topic stacks
Provisions the two shared dependencies procurement-ingest imports by name,
ahead of its migration from mgmt to seahaven-prod:
- dynamodb-cmk-prod: second DynamoDbCmkStack instance (same stack name,
prod account) creating alias/seahaven-dynamodb + the
/seahaven/dynamodb/cmk-arn SSM param. Adds a cross-account key-policy
statement so the mgmt seahaven-slack-bot roles can keep reading the
CMK-encrypted purchase-orders table after it moves (ViaService +
PrincipalArn-wildcard scoped; identity-policy half lands in the
slack-bot repo's cutover PR).
- alarm-topic-prod: codified site-alerts SNS topic + seahaven-alarm-topics
CMK with the cloudwatch.amazonaws.com publish grant (mirrors the working
mgmt pattern; mgmt's topic remains CLI-managed debt).
- deploy.yaml: both appended to the deploy-prod job's explicit stack list
(SH-ORG-005 rule: unlisted stacks silently never deploy).
* fix(scripts): account-id assertion in cfn-stack-decommission; complete the aws-cdk-lib 2.262.0 bump (patched brace-expansion); document CMK cutover trap
- cfn-stack-decommission.sh: --account-id is now REQUIRED and asserted
against sts get-caller-identity before anything runs. Stack names are no
longer org-unique (seahaven-dynamodb-cmk now exists in mgmt AND prod), so
a name-only lookup under the wrong ambient profile could report or delete
the wrong account's stack (security-review LOGIC-001).
- package.json/lock: PR #56's bump-for-patched-brace-expansion landed the
commit title but not the pin; package.json still said 2.261.0 and the
lockfile still resolved brace-expansion 5.0.6 (GHSA-3jxr-9vmj-r5cp HIGH,
blocking the pre-commit scanner). Pin 2.262.0 and regenerate; npm audit
now clean.
- bin/app.ts comments: slack-bot cutover MUST grant the PROD key ARN, never
the account-local mgmt SSM param (LOGIC-005); failed-first-create orphan
CMK recovery note (LOGIC-004).
* refactor(prod): drop cross-account CMK grant (slack-bot decommissioned 2026-07-23)
The AllowMgmtSlackBotReadViaDynamoDb key-policy statement targeted the
seahaven-slack-bot roles, which were decommissioned 2026-07-23. Its successor
sh-mcp is undeployed and uses same-account DynamoDB access, so no cross-account
reader of the CMK-encrypted purchase-orders table exists. The prod CMK + SSM
param + alarm-topic stacks remain (procurement-ingest still imports them). Add
a scoped cross-account grant if/when a real cross-account consumer deploys.
cfn-stack-decommission.sh: report-by-default stack retirement; pre-flight
predicts DeletionPolicy:Retain orphans + consumed-export blocks before delete
(distilled from the LedgerFlow decommission). --execute to act.
resource-usage-probe.sh: is-it-used probe (RDS connections/Lambda invocations/
DDB capacity/EBS attachment) to choose retire-vs-harden before acting on an
encrypt/migrate finding (the database-1 H-19 lesson).