Skip to content

Merge master into jkodroff/ai-infra-ia - #22434

Merged
CamSoper merged 120 commits into
jkodroff/ai-infra-iafrom
claude/ai-infra-ia-conformance-419zu5
Oct 22, 2026
Merged

CamSoper merged 120 commits into
jkodroff/ai-infra-iafrom
claude/ai-infra-ia-conformance-419zu5

Conversation

@CamSoper

Copy link
Copy Markdown
Contributor

Proposed changes

Brings current master into the branch for #22261 so it's mergeable again. No changes to the restructure itself -- every page, alias, and link edit from #22261 is exactly as Josh left it.

The diff is big (about 4,100 files) because it's 119 commits of master, mostly regenerated SDK docs. The only thing that needed a human decision is one merge conflict:

I also swept the merged tree for links to the old /docs/ai/neo/, /skills/, /mcp-server/, and /cli-for-agents/ URLs that master might have added since #22261 branched. There aren't any outside alias blocks and blog posts. Nothing on master touched content/docs/ai/ in that window.

I didn't run make lint locally, so CI is the first real check.

Related issues (optional)

Targets #22261, which closes #22252.


Generated by Claude Code

CamSoper and others added 30 commits October 12, 2026 18:51
~/.pr-review.yml gains an optional board_url key. The skill republishes
the board to it, so every session updates the same link instead of
minting a new one, and writes it back after the first publish.

A config file with no `me:` now takes its lanes from GitHub team
memberships, the same as having no file at all, so a file holding only
board_url doesn't widen the board to every lane.

Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
…ed ack (#22254)

* Collapse duplicate Sentinel status comments and spell out the oversized ack

Overlapping Sentinel runs (no concurrency group, by design) raced the
status-comment upsert: two runs that both listed before either posted each
created a SENTINEL_STATUS comment. Only the oldest was ever patched again,
so the second froze on its first verdict. 6 of the 100 newest PRs carry a
pair, e.g. #22251 (opened as draft, marked ready 19 s later)
and #22154 (a bot lane opening and labelling in one second).

update_status_comment now keeps the oldest bot copy, deletes the rest, and
re-lists once after a first POST to catch the run it raced. A racer's
duplicate DELETE 404s harmlessly, and PRs that already carry a pair heal
on their next evaluation.

G5's red message said only "include sentinel:oversized-ack in the approval
body". It now says who acks (the G3 approver), where the string goes (the
Approve review's comment, or the exact gh pr review command), how to fix an
approval given without it, and what doesn't count (a PR comment, a line
comment, an approval of an earlier commit). Triage's oversized advisory
and CONTRIBUTING now mention the ack too, since that's where authors and
reviewers first hear about the oversize.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015tj2ggCAdn9zntsjXctBBJ

* Make the board age test independent of today's date

test_a_row_carries_its_age_without_crowding_the_meta_line renders a row
from the shared stampable() fixture, whose created_at defaults to
2026-09-10, against the real clock. That row crossed the 30-day amber
threshold on 2026-10-10, so the "plain age before 30 days" half of the
assertion has failed on master and on every PR touching scripts/review-v3
since (#22250's review-pipeline-tests run included). Give the
fresh row a date relative to now.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015tj2ggCAdn9zntsjXctBBJ

---------

Co-authored-by: Claude <[email protected]>
Adds a Cloud SDK concept page under Administration concepts, with
install steps and verified examples in TypeScript, Python, Go, .NET,
and Java, plus a note on date-based versioning.

Adds reference-doc generation following the existing SDK pattern:
TypeDoc, Sphinx, and DocFX configs; a parameterized gen_javadoc.sh and
javadoc_seo_postprocess.py (default output unchanged); and four
pulumi-cloud-sdk-*-docs workflows that derive the release tag from the
package version. Go links to pkg.go.dev.

Also adds Cloud SDK exceptions to the CloudFront SDK redirects, the
versioned-docs selector/backfill wiring, reference hub cards, nav
entries, and cross-links.

Fixes #22247

Co-Authored-By: Claude Opus 5.5 <[email protected]>
… govern, trust, and repeat (#22268)

* docs(events): add Putting agents to work workshop (2026-10-28)

Agent-driven orchestration you can govern, trust, and repeat — a
60-minute virtual workshop presented by Yosef Ejigu, gated with the
HubSpot form and Salesforce campaign from MA-1018.

Co-Authored-By: Claude Opus 5 <[email protected]>

* feat(events): add social cards for the Oct 28 agents workshop

Render the five event card sizes with /event-meta-image and wire the
landscape and square cards as meta_image and meta_image_square. The
1080x1080 card doubles as the Luma cover.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5 <[email protected]>
…I credential-error page (#21885)

* Add UnrecognizedClientException coverage and internal links to AWS CLI credential-error page

Adds an UnrecognizedClientException section (H3 + FAQ entry) to the
consolidated AWS CLI credential-error page, matching the existing
pattern for the other five documented errors.

Also weaves contextual internal links to that page into five adjacent
AWS/ESC pages (docs get-started, aws-login, two blog posts, and the
AWS Secrets Manager what-is page) so readers hit the right explanation
from wherever the error actually surfaces.

* Cite AWS STS error reference for UnrecognizedClientException claim

Addresses review finding F6: link the AWS documentation source
instead of attributing the claim without a citation.

---------

Co-authored-by: workprentice <[email protected]>
…/migrating-from-cdk/migrating-existing-cdk-app.md (#22262)

Automated existing-content review.

Co-authored-by: Claude <[email protected]>
…earch.md (#22263)

Automated existing-content review.

Co-authored-by: Claude <[email protected]>
…console.md (#22264)

Automated existing-content review.

Co-authored-by: Claude <[email protected]>
* Refresh Top 15 Python Tools for DevOps for 2026

* Address review: soften Scapy and MCP claims, link docker-py 7.2 notes

---------

Co-authored-by: workprentice <[email protected]>
…udies (#22241)

Clears the non-historical Pulumi Insights findings from #21133.

Co-authored-by: Claude Opus 5.5 <[email protected]>
…claims once (#22269)

* Keep oversized review cards publishable and ask about private-source claims once

#22200's review failed to publish on three runs in a row: the
author card came out at 73, 76, then 80 KB, and pinned-comment.sh refuses
anything over 60,000 bytes and never splits a v3 card. Every retry composed
the same card and failed at the same step, after the full model pass.

Two causes, two fixes.

The PR documents a feature whose implementing change
(pulumi/pulumi-service#49283) is private to the review's token, so every
claim about the new behavior came back `unverifiable` and became its own ❓
row and Do-this block: 85 of them, each asking the author the same thing.

- verify-claims.py now probes each implementing ref the PR body cites and
  records the ones whose repo 404s in meta.impl_refs_unreadable. Only a
  404 counts; a timeout or 5xx says nothing about access.
- compose-review.py asks about the ordinary pass1 unverifiables those refs
  explain as one group question (3+ members): one F-id, a Where of `—`,
  and a Do-this block it writes in full with a per-file claim list.
  Turn-cap, source-discipline, outage, pass2, and pass3 unverifiables keep
  their own rows. The evidence record carries `members`, and the brief's
  Facts line counts a group as its members.

Nothing measured the card before publish, so any PR with enough findings
could hit the same wall.

- build-evidence.fit_author_card runs where both lanes finish a card and,
  while it's over 58,000 bytes, sheds what the evidence page also carries,
  cheapest first: ❓ row links, ✅ row links, ❓ Do-this blocks (never a
  group's), 🚨 row links, a group's claim list, 🚨 Do-this blocks. Rows
  always stay. fit_brief_card does the same for ⚠️ links.
- The evidence page now renders each finding's text, Do-this detail, and
  group members, so what the card sheds is still one click away.
- The update lane restores shed blocks from evidence when a fitted card
  shrinks, then fits again.

Replayed against #22200's real artifacts: the 80,205-byte card that failed
fits at 22,615 bytes, and composing with the carve-out takes it from 88
blocking items to 38, an estimated 43 KB before any fitting.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_014Fy6aYYUwGgGVjX2Kb6cfD

* Stop verifiers spending Opus turns on unreadable refs; make the group block composer-owned

On #22200, 98 of 236 claims tried to read
pulumi/pulumi-service#49283 even though the review's token can't, at 4.3
turns apiece against 3.5 for the other pass1 claims, and accounted for 60%
of the run's uncached input tokens. The probe already knows which refs are
unreadable before any verifier starts, so:

- build_user_message names an unreadable ref instead of listing it to read,
  and tells the verifier to settle the claim from what it can read or
  return `unverifiable` now.
- exec_gh_query refuses a query against an unreadable repo (-R, --repo=,
  repos/…, repo:, a github.com URL) without running gh, and says why.
- The 404 check reads stdout as well as stderr.

The group question's Do-this block is written in full by the composer, and
a model edit to it (a second **Fix:**, a dropped claim list) would fail
validation and cost the whole review. The base record now carries the
block text in `detail`, normalize-v3-draft.py restores it before validation
(rule 10) and regenerates a deleted one from it, and an update-lane retext
keeps the claim list.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_014Fy6aYYUwGgGVjX2Kb6cfD

---------

Co-authored-by: Claude <[email protected]>
#22276)

- leg.colorado.gov/bills/sb25b-004 has returned HTTP_406 to the crawler on
  at least 8 daily runs since 2026-09-19 (most recently 2026-10-12/13),
  always resolving 200 for a browser-like request. Add HTTP_406 to the
  externalErrorReasons filter alongside HTTP_403/401/415, which already
  treat this class of content-negotiation/bot-protection response as
  acceptable for external links.
- Two web.archive.org snapshot URLs (in blog/next-level-iac-breakpoint-debugging
  and blog/next-level-iac-package-ecosystems) have intermittently returned
  ERRNO_ECONNREFUSED across at least 4 runs, always resolving 200 on
  recheck. Add the specific snapshot URLs to the exclusion list rather
  than the whole archive.org domain, so a genuinely dead snapshot is
  still caught.

Both patterns were previously re-verified and left unactioned in every
daily fix-broken-links PR (per that skill's "don't add it unless it's a
recurring offender" guidance) without ever crossing into the exclusion
list — there's no automatic allowlisting, and the daily PRs kept treating
each occurrence as unproven. This closes the loop for these two specific,
well-established repeat offenders.

Co-authored-by: Cam Soper <[email protected]>
Add David Pilato (Principal Developer Advocate, Elastic) to the
presenters of the Give your coding agent an (Elastic) memory workshop
and regenerate the event social cards with both speakers.
Automated existing-content review.

Co-authored-by: Claude <[email protected]>
These posts carried a canonical_url pointing at a *different* internal
page (a reference doc, the registry, or in one case another blog post)
despite not being duplicate content. Most were added in #14767 as an SEO
play to funnel link equity to docs, but rel=canonical tells search
engines the post is a duplicate and to index the target instead — so
these were deindexing the posts in favor of unrelated pages.

Leaves esc-sync-with-iac untouched: its content genuinely migrated into
the docs guide it points to (and the post says so), the one legitimate
canonical. External syndication canonicals are also untouched.
…r with Pulumi (#22285)

Adapts the APN co-authored draft for the Pulumi blog. Adds a Tatiana Cooke
author profile for the blog byline (separate from her leadership entry).
* Add oidc and debug-oidc-claims ESC provider pages

Document fn::open::oidc, which mints an OIDC v2 token for an audience
the user chooses, and debug-oidc-claims, which previews a token's claims
without signing one. Add both to the provider catalogs, and point
aws-login and vault-login readers who need a raw token to fn::open::oidc.

The Inputs and Outputs tables are hand-written because the ESC schema
fetch cannot see org-gated providers yet.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Add a custom-audience OIDC guide for ESC

Explain the two ESC token issuers on the Configuring OIDC page, add the
v2 claim table, and add a guide for configuring a relying party to trust
fn::open::oidc tokens, with Cloudsmith, AWS IAM, and Aembit examples.
Link the vendor OIDC guides to it, and add Aembit and Cloudsmith to the
Vale vocabulary.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Apply review feedback to the ESC custom-audience OIDC docs

Drop the AWS IAM example from the custom-audience guide and steer AWS,
Azure, and Google Cloud readers to the vendor login providers. Remove the
v2 issuer notes from the four vendor OIDC guides, since their readers never
touch the v2 issuer. Name the generic provider and its issuer in both
catalog rows, and leave the configuring-oidc intro sentence as it was.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Update the Cloudsmith OIDC section from a live workspace test

Ran the section end to end against a Cloudsmith workspace and the
https://api.pulumi.com/oidc/v2 issuer on 2026-10-12. The ESC YAML, the
exchange command, and the X-Api-Key header worked as written.

Add what the test showed the section was missing: create the service
account first (Manager or Owner role), enable the provider, and always
require sub, since an aud-only provider accepted tokens from other
environments. Show the org-wide forms that worked (a trailing .* on sub,
or the https://pulumi.com/org_id claim). Note that Cloudsmith requires no
particular audience, that ${VAR} in a pulumi env run command expands to
empty, that the exchanged token lives about two hours, and that
Cloudsmith returns one generic 401 for a bad provider URL, an expired
token, or a claim mismatch. Remove the TODO marker.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01CThVPb3ACnmoDNmJbpedhr

* Apply the OIDC v2 acceptance-test findings to the ESC docs

Fold in what a black-box run against production on 2026-10-12 showed
the pages were missing or had wrong.

Trust rules: every organization shares the v2 issuer and any
organization can mint a token for any audience, so a relying party that
checks only iss and aud accepts tokens from other organizations. Say so
in the claims section and pin every example to sub or org_id. Note that
some relying parties, AWS IAM among them, cannot read the custom claims.

Vault: replace the untested bullets with the commands that ran end to
end (role_type=jwt, required bound_audiences, bound_subject or
bound_claims, the write-based login) and the environment that exports
the token. Soften the one-issuer-per-mount claim.

Provider page: most schema refusals fire at save, not open, so split
the troubleshooting symptoms by phase and quote the full strings. Add
the relying-party clock-skew and credential-lifetime note, the warning
that pulumi env run expands ${NAME} in its own arguments, and the audit
event name.

Debug page: the vendor preview is gated like the v2 form and omits iss,
iat, and exp. Add a troubleshooting section for the wrong-form and
unsaved-document refusals.

Subject: an environment that only imports the block shows a subject no
token carries, so say to copy it from the declaring environment.

Index page: signed vendor tokens carry org and env claims the table
left out.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Align the OIDC v2 findings commit with the test evidence

Restore the Vault clock_skew_leeway=-1 advice the findings commit
dropped. Cut two claims the evidence does not support: the vault-login
roles expecting v1 subjects, and the console label for the audit event.
Put the credential-lifetime sentence in the active voice.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01CThVPb3ACnmoDNmJbpedhr

* Add a JFrog Artifactory section to the custom-audience OIDC guide

The steps match a live run against Artifactory 7.173.4. JFrog compares
the audience exactly and skips the check when the field is blank, so
the section says to set it. The identity mapping pins sub and shows the
env:* glob as the org-wide form.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01CThVPb3ACnmoDNmJbpedhr

* Add the AWS subject glob and measured clock-skew allowances

Show the AWS IAM StringLike form of the org-wide subject match beside
the Vault glob. Give the clock-skew figures measured against AWS,
Vault, and JFrog in the provider page's lifetime section.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01CThVPb3ACnmoDNmJbpedhr

* Drop the rollout notes and the ESC expansion from the OIDC v2 pages

These pages ship once fn::open::oidc is on for every organization, so
the "turning on organization by organization" callouts, the
organization-only subject note, and the "provider not enabled"
troubleshooting entry describe a state no reader will see. Remove them.

Write "Pulumi ESC" without the parenthetical expansion; the rest of the
docs assume the term. Replace the sentence that named the feature with a
pointer to the relying-party guide.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Add the launch post for fn::open::oidc

A product post announcing OIDC tokens for custom audiences in Pulumi
ESC, written to the conventions of the 2026 ESC and security launch
posts: a problem-first intro, the environment YAML within the first
section, a trimmed decoded token, one worked relying party (HashiCorp
Vault, as verified in the 2026-10-12 acceptance run), the shared-issuer
rule to pin the subject, and a numbered "Get started" close that links
the provider reference and the relying-party guide.

The date is a far-future placeholder so production skips the post until
launch while the PR preview still renders it. The feature image is left
for /blog-feature-image or design; nothing is committed in its place.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Date the fn::open::oidc post and render its feature image

Set the publish date to 2026-10-15. Render feature.png with
/blog-feature-image from the circle shape template and the Phosphor
fingerprint icon, and cache that icon in the skill's assets as the skill
asks.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Open the fn::open::oidc post on the value and swap the worked example to Aembit

The first paragraph is now one sentence stating what changed. The worked
example uses Aembit instead of HashiCorp Vault, matching the relying-party
guide's Aembit section, and the social copy follows.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Explain why identityToken.version exists and stop belaboring it in the post

The provider reference now says in two sentences what the version pins and
why the input has no default. The schema tables say to set v2 instead of
calling it the only accepted value, and the blog post names the input
without explaining the versioning.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Tighten the leaked-key sentence in the fn::open::oidc post

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Teach the heading rule the OIDC relying-party vendor names

Aembit, Cloudsmith, JFrog, and Artifactory are proper nouns that now appear
mid-heading in the custom-audience guide and the fn::open::oidc post. The
post also drops a possessive the spell checker could not resolve.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Finish the Aembit section of the custom-audience OIDC guide

The Aembit steps were drafted from vendor docs. A live run against an
Aembit tenant on 2026-10-12 confirmed them and found the gaps this fills:
the audience guidance, why the subject must be pinned (Subject has no
wildcard; org-wide trust uses a custom claim rule on
https://pulumi.com/org_id), the credential provider, server workload, and
access policy, the /edge/v1/credentials call that resends the OIDC token,
where the Edge URL and client ID come from, and the generic 401, the
discovery check on save, and the five-minute expiry grace. The run used
the management and Edge REST APIs, not the UI, so UI locations stay loose.
Drops the section's TODO.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01CThVPb3ACnmoDNmJbpedhr

* Name the duration the Cloudsmith token ignores

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Drop the issuer URL from the LinkedIn copy

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Stop calling the fn::open::oidc feature "v2" in prose

"OIDC v2" collides with the OIDC Issuers feature in Access Management, so
the pages now call this general OIDC in ESC. The identityToken.version
value, the issuer URL, and the quoted error strings are unchanged.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Drop Vault and AWS STS from the blog's relying-party lists

Vault already has vault-login, and the guide has no AWS section.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Call the token short-lived in the blog intro

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Explain the trust check once in the blog

The intro said any service that trusts the issuer can exchange the token,
which is what the pin-the-subject section warns against. The trust check
now lives in that section, and the two earlier mentions point at it.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Say fixed set of providers, not clouds

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Spell out what a leaked key costs

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Add a short agents paragraph to the blog

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Match the blog's Aembit Edge API URL to the guide

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Say who can mint a token when the subject is pinned

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Recommend pinning the exact subject and drop the org_id guidance

Trusting a whole organization means trusting anyone who can create or
edit any environment in it, which throws away the per-environment
boundary the ID-based subject gives. Org-wide trust now appears only as
a sub wildcard with the tradeoff stated, and the import pattern is the
recommended way to share one trust entry.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Group the relying-party examples under one heading

The four services read like the only ones supported.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Shorten the oidc provider's catalog row

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Warn about pinning the subject on the provider page

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Open the blog with why the reader should care

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Rename the token issuers section to token formats

"OIDC issuers" in Pulumi Cloud means the external issuers Pulumi trusts,
the opposite direction from this section.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* docs: drop Vault and AWS from the general OIDC guide

ESC already exchanges tokens with Vault and AWS through vault-login and
aws-login, so the relying-party guide for fn::open::oidc no longer carries
a Vault worked example. The wildcard and clock-skew asides now cite
Cloudsmith, JFrog, and Aembit, the services the guide documents.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Update content/docs/esc/providers/login/oidc.md

Co-authored-by: Christian Nunciato <[email protected]>

* blog: move the general OIDC post to Wednesday 2026-10-14

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* docs: debug-oidc-claims requires identityToken.version in both modes

Version v1 previews the vendor login claims and v2 the fn::open::oidc
claims; a block without identityToken.version no longer selects a mode.
Matches pulumi/pulumi-service branch dgrove/debug-oidc-claims-require-version.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* docs: document actor_id and the canonical environment claims

The general OIDC claims tables gain actor_id, current_env_version, and
root_env_version, state the three login shapes actor can carry, and say the
environment names always include the project. Matches pulumi/pulumi-service
#50716 and #50717.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* docs: lower the OIDC audience cap to 255 bytes

Matches pulumi/pulumi-service#50717, which caps the audience at 255 because AWS client IDs stop
at 255 and GCP audiences at 256.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* blog: name the services the token can reach

ESC is itself a secrets broker and "workload identity platform" names nothing a reader can picture, so
the intro, the LinkedIn copy, the weak-link section, and the provider page now name Cloudsmith, JFrog
Artifactory, and Aembit instead.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* blog: fold the intro's token sentences into one

The intro said "mint a token for any service" three times, and the last sentence let any service that
trusted the environment exchange the token when only the audience can.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* blog: state what each trust policy field confirms

The section led with the failure case and implied the service checks the subject on its own, when the
policy has to ask for it.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* docs: trim the identityToken.version rationale

Readers need the reason the input has no default, not the v1 history.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* docs: root_env_version carries a tag when the open named one

Matches pulumi/pulumi-service#50717, where a root opened at a tag now reports the tag rather than
the revision it resolved to, as an import of the same tag already did.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* docs: actor_id is the ID of what actor names

Matches pulumi/pulumi-service#50716: a team token's actor_id is the team's ID and an
organization token's is the organization's ID.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* blog: move the general OIDC post to Thursday 2026-10-15

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* Update content/blog/esc-oidc-tokens-for-any-service/index.md

Co-authored-by: Daniel Perlovsky <[email protected]>

* docs: link the general OIDC pages from the ESC parent pages

The landing page card, the guides index, and the OIDC guide's provider list each named the vendor
providers only, so nothing above the provider catalog pointed at the oidc provider or the
custom-audience guide.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* blog: strip a trailing space that failed markdownlint

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01L5qtGZFNxMxwbJXZH33AL2

---------

Co-authored-by: Claude Fable 5.1 <[email protected]>
Co-authored-by: Christian Nunciato <[email protected]>
Co-authored-by: Daniel Perlovsky <[email protected]>
* docs: make Anthropic the worked example for general OIDC

The blog's worked example is now Anthropic's workload identity federation, and the relying-party
guide gains an Anthropic section between JFrog Artifactory and Aembit: the Custom OIDC issuer
setup, the rule that pins the subject and audience, the environment that exports the token beside
the four Anthropic IDs, the raw exchange, and the single-use token behaviour. Vendor lists on the
guides index, the provider page, and the blog's social copy name Anthropic too.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* docs: correct the Anthropic example after a live run

The audience is Anthropic's fixed value, not a choice. The access token lasts for the rule's
lifetime, 10 minutes by default, not for the ESC token's. The Console's issuer form labels,
where each ID lives, the conditional workspace ID, and the Admin API's OAuth requirement are
spelled out. The Anthropic section now counts as run end to end.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

* docs: put the Anthropic example first in the relying-party guide

The shell-interpolation note moves with it, and the other three examples now refer to it there.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VmxiXuQGvyeGqCpJBYGcR2

---------

Co-authored-by: Claude Fable 5.1 <[email protected]>
…ptions/aks-hosted.md (#22296)

Automated existing-content review.

Co-authored-by: Claude <[email protected]>
pulumi-bot and others added 23 commits October 21, 2026 15:40
…/debugging-providers.md (#22405)

Automated existing-content review.

Co-authored-by: Claude <[email protected]>
…ptions/eks-hosted.md (#22378)

Automated existing-content review.

Co-authored-by: Claude <[email protected]>
…/migrating-from-cdk/using-pulumi-cdk.md (#22379)

Automated existing-content review.

Co-authored-by: Claude <[email protected]>
…search.md (#22381)

Automated existing-content review.

Co-authored-by: Claude <[email protected]>
* blog: self-hosted AI infrastructure with Pulumi AICR

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>

* blog: add feature image for AICR post

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>

* blog: reframe AICR post as provider announcement

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>

* Update content/blog/self-hosted-ai-infrastructure-pulumi-aicr/index.md

adding hypen for style

Co-authored-by: Christian Nunciato <[email protected]>

* Update content/blog/self-hosted-ai-infrastructure-pulumi-aicr/index.md

Co-authored-by: Christian Nunciato <[email protected]>

* Update content/blog/self-hosted-ai-infrastructure-pulumi-aicr/index.md

Co-authored-by: Christian Nunciato <[email protected]>

* Update content/blog/self-hosted-ai-infrastructure-pulumi-aicr/index.md

Co-authored-by: Christian Nunciato <[email protected]>

* Update content/blog/self-hosted-ai-infrastructure-pulumi-aicr/index.md

Co-authored-by: PYoakum <[email protected]>

* Update content/blog/self-hosted-ai-infrastructure-pulumi-aicr/index.md

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Minor typo and wrapping fix

* Apply suggestion from @cnunciato

* Apply suggestion from @cnunciato

---------

Co-authored-by: Peter Yoakum <[email protected]>
Co-authored-by: Claude Sonnet 5.5 <[email protected]>
Co-authored-by: Christian Nunciato <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Resolve the billing-managers.md conflict by keeping master's sentence-cased
"billing manager" and this branch's updated Neo usage limits link.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01TCgHH2NDHANbz8V8F7BLey
@github-actions

Copy link
Copy Markdown
Contributor

Sentinel — merge gate status

Draft PRs are not gated; the sentinel evaluates on ready-for-review.


Need help, or think a gate got it wrong? Ask in #docs on Slack.

@CamSoper
CamSoper merged commit 6467df3 into jkodroff/ai-infra-ia Oct 22, 2026
12 checks passed
@CamSoper
CamSoper deleted the claude/ai-infra-ia-conformance-419zu5 branch October 22, 2026 17:11

This branch had an error being deployed

1 failed and 1 inactive deployments
testing — 6467df35 Deployed Oct 22, 2026 by CamSoper via Do cleanup #14875
production — 6467df35 Deployed Oct 22, 2026 by CamSoper via Record review outcome #14875
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.