Skip to content

Add AI skills sections to documentation for improved guidance - #130

Open
Akshat0694 wants to merge 18 commits into
mainfrom
f/agent-skills
Open

Akshat0694 wants to merge 18 commits into
mainfrom
f/agent-skills

Conversation

@Akshat0694

Copy link
Copy Markdown
Member

What does this change?

Adds AI-agent guidance for writing StackGuardian Terraform configuration, and surfaces it on the
documentation pages themselves.

Seven skills under .claude/skills/, one per area — stackguardian-provider (router),
-resource-ids, -workflows, -templates, -policies, -access, -import. Each is a SKILL.md
whose frontmatter says when it applies, following the structure used by
hashicorp/agent-skills: narrow scope, ~600 words, and
routing to depth rather than restating it. Because these live in the provider repo, they point at
docs/guides/ as their reference layer instead of duplicating it.

The content is deliberately limited to what the schema cannot tell you — the mistakes that pass
terraform validate and fail later, or worse, succeed while meaning something other than intended:

  • stackguardian_role expands path values as a cartesian product; rolev4 maps them one to one, so
    converting means an alternation string ("a|b|c"), not a resource rename
  • An inline policy sets both policy_input_data and policy_vcs_config; schema_type is
    TIRITH_JSON, since RAW_JSON is accepted but leaves a permanent diff
  • Secret references use a double colon — ${secret::<name>}, written $${ in Terraform
  • Three nesting modes that intuition reverses: mini_steps…email.<event> is a list,
    vcs_triggers.push is a map keyed createWfRun, deployment_platform_config is a list

A "Building this with AI" section on all 43 documentation pages, naming the skill to load plus
that page's specific warning. The warnings are written for both audiences — "path values map one to
one, unlike stackguardian_role" is as useful to a human reading the registry as to an agent
generating from it.

Cross-agent packaging so this isn't Claude-only: AGENTS.md (Codex, Gemini CLI, Cursor, Zed,
Aider), .github/copilot-instructions.md, .cursor/rules/stackguardian.mdc,
.windsurf/rules/stackguardian.md. The adapters are thin pointers carrying only the always-apply
rules; depth stays in the skills.

scripts/sync-ai-skills-sections.py generates the sections from a single mapping and replaces
content between <!-- AI-SKILLS:START/END --> markers, so it is idempotent and a wording fix means
editing one dict entry rather than 43 files.

Closes #

Type of change

  • Bug fix
  • New resource or data source
  • New attribute or behaviour on something existing
  • Documentation only
  • Build, CI or tooling

Checklist

  • make build succeeds.
  • CHANGELOG.md is updated (see CONTRIBUTING.md). — see notes below

If you touched a schema, docs-templates/, or docs-examples/:

  • make docs-generate has been run and the resulting docs/ changes are committed.
    docs/ is generated — never edit it by hand.
  • make docs-validate-examples passes.

If this is a breaking change or changes an existing resource's behaviour:

  • N/A — no schema, resource, or provider-behaviour change. Only docs-templates/, generated
    docs/, and new agent-facing files.

Notes for reviewers

On the unticked changelog box. CHANGELOG.md states that releases from 0.1.0 onward are
documented on the GitHub releases page, generated from merged pull requests, and that the file is
kept for historical reference. CONTRIBUTING.md line 35 still says to update it before merging. I
followed the file rather than the instruction and left it untouched — but the two contradict each
other, and that is worth resolving separately.

These sections publish. They render on the Terraform Registry alongside the existing
docs-revamp banner, so each page carries two notices. That is why the earlier "Placeholder." text
was rewritten into something a human benefits from.

One sequencing constraint. The sections link to .claude/skills/ on main, which only exists
once this merges. If a release is tagged before then, those links 404. Merging this ahead of the
next tag avoids it.

Verification. make build · make docs-generate idempotent · make docs-check passes, so
docs/ is in sync with its sources · make docs-validate · make docs-validate-examples
77 passed, 0 failed · all skill frontmatter parses with name matching its directory · all
cross-references resolve.

Out of scope, noticed while here. .claude/skills/create-resource/ (pre-existing, from
4a60a0b) has name: Create Resource where its directory is create-resource. Some loaders key on
the directory and some on the field, so that mismatch may stop it resolving — a one-word fix, but
not this PR's business.

hllvc and others added 18 commits August 31, 2026 17:47
The pinned v0.18.0 cannot reproduce our own committed docs -- it corrupts
nested-schema headings, collapsing distinct blocks onto duplicate titles.
v0.25.0 regenerates docs/ byte-identically, so the pin was simply wrong.

Add `make docs-check`, which regenerates and fails if docs/ differs, and wire
it into CI. Without it a schema change silently leaves the published docs stale,
which is how they drifted in the first place.

Also pass --provider-name to docs-validate explicitly; it previously worked only
because CI checks out into a directory named terraform-provider-stackguardian.
Attribute text on the Registry comes from MarkdownDescription, and 226 of the
2001 documented attributes had none -- 22 more shipped an empty string. Most of
the missing text already existed as a constant and had simply never been wired
in: data-source schemas were written as bare `Computed: true` while their
resource twins documented the same fields.

Mirror each data source from its resource twin, and add the resource and
data-source level summaries that 20 of the 32 schemas were missing. Only one
attribute is left undocumented -- is_committed, whose meaning is not recorded
anywhere in the code or the SDK.

Document the path-form IDs the platform uses (/integrations/<name>,
/secrets/<name>, /<org>/<name>:<rev> and the :latest tag) on every attribute
that takes one; most previously gave no format at all. Fix descriptions that
were wrong rather than merely thin: VCSTriggers pointed workflow_template users
at a vcs_config attribute that resource does not have, RunnerConstraintsNames
named an enum value that does not exist, and several constants shipped typos and
placeholder text to the Registry.

Mark stackguardian_role deprecated at the schema level so Terraform warns at
plan time, and clear it on rolev4, which inherits role's schema wholesale.
The templates dropped the two `{{ .Description }}` renders that tfplugindocs'
own default template has, so every schema-level description was invisible on the
Registry -- the BETA notice on stack_template had not rendered for months. Add
both, and give every page a domain subcategory so the Registry sidebar groups
into Access Control, Workflows, Templates, Infrastructure and Outputs instead of
one flat list of 32 entries.

Fix titles that named the wrong resource. The policy resource page called itself
stackguardian_workflow_group and the policy data source called itself
stackguardian_role -- both live on the Registry today. Fourteen pages carried a
wrong page_title, ten data sources were labelled "Resource", and four import
commands named a resource type that would fail if copy-pasted.

Replace the hand-written HTML banners with schema-driven notices, and add
explanatory prose to the 25 pages that had none: nested workflow groups and the
adopt-on-collision behaviour, workflow_git's user-chosen id and trigger
rollback, how a connector is referenced, the container/revision relationship.

Add nine guides, where there were none: Installation, Getting Started, Object
Model, Resource IDs, Templates and Revisions, Access Control, Importing Existing
Resources, Troubleshooting and Team Onboarding. The provider landing page now
opens with a description and an index of them.
Add a validation harness -- scripts/validate-examples.sh, wired into CI as
`make docs-validate-examples`. It builds the provider, serves it from a local
filesystem mirror and runs `terraform validate` on every example. No API calls
and no credentials. It immediately found examples that could never have worked:
the workflow_template data source omitted its required id and set a Computed
attribute, workflow_template_revision omitted two required arguments, and the
workflow_group data source referenced an undeclared resource.

Rewrite the quickstart, which used stackguardian_workflow -- a resource type
that has not existed for a long time -- so the "minimal working configuration"
the README points at failed at plan. It now builds a real deployment:
workflow_group, connector, workflow_git, with the connector wired in rather
than hardcoded.

Give all 17 data-source examples explanatory comments, where none had any, and
show what you would look each one up for. Remove the hardcoded integration_id
and iac_template_id literals so the connector-to-workflow and
template-to-revision-to-workflow chains are demonstrated somewhere.

Fix the onboarding projects: three different wrong provider sources, an internal
QA endpoint, a quoted interpolation that silently produced a literal string, and
an import script that used API paths where the provider expects bare names and
referenced two resource types that do not exist.

Refresh the contributor docs. Both guide-asset READMEs pointed at directories
that were never created, CODE_OF_CONDUCT still had a placeholder contact,
CHANGELOG stopped at 0.1.0 with no pointer to releases, and CLAUDE.md described
a directory layout and a resource list that no longer match the code.
Every enum rendered as a bare list of backend tokens -- "Options: FORM_JSONSCHEMA,
RAW_HCL, RAW_JSON, NONE" -- with nothing saying what any of them does. The API
spec cannot help here: 39 of its 47 enum descriptions are tautological, of the
form "GITHUB_COM - GITHUB_COM".

Gloss each value instead: what the input schema types mean, what each policy
action does on pass and on fail, which cloud and VCS provider each connector
kind targets, and where PLAIN_TEXT and SECRET_VALUE differ. Link out to
docs.stackguardian.io per connector kind where a page exists.

Document policy_type, which was previously just `"GENERAL" or "FILTER.INSIGHT"`.
GENERAL is the enforcement policy; FILTER.INSIGHT filters findings out of the
Insight dashboard and takes neither scope nor approval settings -- which matches
the API, where PolicyFilterInsight has no EnforcedOn, Approvers or Tags.

Two fixes this surfaced:

- Attribute descriptions render inline inside a Markdown list item, so a literal
  newline escapes the attribute list and breaks the page. Two descriptions added
  earlier in this branch did that; both now use the inline <ul><li> style the
  rest of the schema uses.
- wf_type inside stack_template_revision listed three values while the workflow
  resources list seven. Stacks mix workflow types, so the narrow list was wrong.

Also correct the policy page prose, which still claimed enforced_on takes the
same paths as a role's allowed_permissions. It does not -- roles take bare
resource names.
Glossing the step template values turned up documented values that do not
exist. Checked every enum in the docs against the API spec and the SDK:

- Environment variable `kind` was documented as PLAIN_TEXT or SECRET_VALUE.
  The real enum is PLAIN_TEXT or VAULT_SECRET (EnvVarsKindEnum in the spec, and
  EnvVarsKindEnumVaultSecret in the SDK). SECRET_VALUE has never existed, so
  anyone following the docs to reference a secret got a value the API rejects.
  It was the most repeated enum token in the docs, 92 occurrences. `secret_id`
  named a third value, SECRET_REF, which does not exist either. No test covers
  the secret path, which is why this survived.
- workflow_step_template `source_config_kind` listed DOCKER_IMAGE, GIT_REPO, S3
  and `source_config_dest_kind` listed CONTAINER_REGISTRY, GIT, S3. GIT_REPO, S3
  and GIT appear nowhere in the spec; both fields are single-valued.
- `wf_type` listed the seven template kinds. WfTypeEnum is TERRAFORM, OPENTOFU,
  CUSTOM, and it backs every wf_type field. A Helm or Ansible template runs as a
  CUSTOM workflow. This also reverts a change earlier in this branch that
  widened the correct three-value list inside stack_template_revision.

`template_type` is now explained as the discriminator across all four template
families -- WORKFLOW_STEP, IAC, IAC_GROUP, IAC_POLICY map to step, workflow,
stack and policy templates -- and noted as read-only, since it is Computed.

Every enum value now rendered in the docs is present in the API spec.

Two step-template constants also embedded literal newlines, which break the
attribute list; both are now inline.
Four more places were still showing bare tokens:

- Stack template `source_config_kind` listed eight values. The API is explicit
  here: it is always `MIXED` for a stack, because a stack groups workflows built
  from different tools and the tool for each one is recorded on that workflow.
  The other values belong on a workflow template.
- `template_type` on the step template revision used a second constant that the
  earlier pass missed, so it still showed the four raw values.
- `vcs_triggers.type` on a workflow template listed three values and ended in a
  dangling comma.
- `vcs_triggers` on workflow_git explained its prerequisites in terms of raw
  values; it now names them and links to the VCS connector docs.

Also promote the `terraform_version` description that was stranded inline in one
data source to the shared constant, so all six users of the field explain the
engine prefix rather than saying "Terraform version to use."

Every enum value in the docs is present in the API spec, and the only remaining
bare list is ENABLED/DISABLED on a schedule, which needs no gloss.
The API stopped accepting 1.6.0 (fixed on main in #119, merged here); align the
example configs and the Templates guide from 1.5.0 to 1.5.7, the version the
test suite now validates against, so copied examples use a known-good value.
- Updated subcategories for data sources and resources to better reflect their purposes, changing "Access Control" to "Access Management" and "Infrastructure" to "Connectors" where applicable.
- Added a new guide on "Access Management" detailing roles and role assignments.
- Created a new guide on "Policies" explaining their purpose and usage in workflow runs.
- Enhanced descriptions and examples in the policy documentation to clarify the policy body sources and their configurations.
- Improved the clarity of output descriptions for various resources, particularly around approvers and schema types.
- Updated links in the "Getting Started" and "Installation" guides to point to the new "Access Management" guide.
- Adjusted the "Object Model" and "Troubleshooting" guides to reflect the updated terminology and concepts.
…feature requests

- Created a bug report template to streamline issue reporting for provider bugs.
- Added a documentation issue template to facilitate feedback on documentation clarity and completeness.
- Introduced a feature request template to gather suggestions for new resources and enhancements.

chore: disable blank issues and add contact links in config.yml

- Disabled blank issues to redirect users to the template chooser.
- Added links to provider documentation, troubleshooting guide, and feedback discussion for better user support.

chore: implement a pull request template for consistent contributions

- Added a pull request template to ensure contributors provide necessary information and follow best practices.

chore: inject a revamp banner into documentation pages

- Added a script to inject a banner indicating that documentation is being revamped, ensuring users are aware of ongoing changes.
- Updated multiple resource and data source documentation files to include the revamp banner for clarity.
- Updated README.md for onboarding to clarify roles, workflows, and permissions.
- Modified import.sh to reflect new resource naming conventions and added workflow import.
- Revised project-01.tf to implement stackguardian_rolev4 roles and improve permission management.
- Enhanced project-02.tf to define hierarchical team roles with distinct permissions for managers and developers.
- Updated TeamOnboarding.md to include new policy examples and clarify the structure of onboarding configurations.
- Updated the Makefile to clarify the purpose of the docs-validate-examples target.
- Revised comments in policy resource examples to specify that approvers can be email addresses or SSO group names.
- Modified Policies.md and ResourceIDs.md to reflect changes in the format of approvers and resource IDs.
- Added a new script (extract-doc-blocks.py) to extract and validate Terraform blocks from documentation prose.
- Enhanced validate-examples.sh to validate Terraform blocks embedded in documentation, ensuring they are type-checked correctly.
- Updated various documentation files to use the new template ID format and improved clarity on approver specifications.
The docs step was last in the job, so a job that stopped at the first
failing step never reached it. That made documentation validation
conditional on the production API being reachable: an unrelated
acceptance-test failure, an unavailable secret, or an API hiccup took the
docs checks with it, and a fork PR without secret access got no signal at
all.

Nothing in that step needs credentials or a network -- the provider is
served from a local filesystem mirror -- and it finishes in a couple of
minutes against the suite's fifteen, so it now runs first and fails fast.

Within the step, docs-validate-examples moves ahead of docs-check for the
same reason: docs-check regenerates docs/ and, under set -eu, a stale
tree would have stopped the run before the examples were type-checked.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Registry navigation sorts alphabetically within a subcategory and offers
no ordering control, so grouping is the only lever. Stack pages were
split across Templates and Workflows, which put two stack_* data sources
at the head of a list headed "Workflows". They now sit in Stacks, and
workflow groups get their own subcategory, leaving Workflows as the
workflow-execution pages and Templates symmetric at four templates by
resource and data source.

The workflow_git example was three thin snippets that declared no
workflow group and set wf_type = CUSTOM against a public repo. It is now
three progressive ones -- minimal, nested group with inputs, and a
production workflow with a cloud connector, private repo, drift
detection, an approval gate, VCS triggers and notifications. Each
declares its own group and references it, so the dependency and the
creation order are visible. Attribute names and nesting modes were taken
from the provider schema rather than written from memory; three would
have been wrong by intuition, since mini_steps email events are lists and
vcs_triggers.push is a map keyed on createWfRun.

Alongside that, three documentation constants:

  - SecretReferenceSyntax, new and shared, describing the
    ${secret::<name>} form. The separator is a double colon; the
    single-dot spelling that appears in some tooling resolves nothing.
    Confirmed against live workflows, where the double-colon form is in
    use and the dotted one matches nothing.
  - EnvVarConfigTextValue was stale: it carried raw HTML styling and
    referred to a kind called TEXT, which does not exist. Rewritten
    around PLAIN_TEXT with the state-exposure warning.
  - WorkflowIacInputDataSchemaType now notes that the platform returns
    NO_CODE_JSON on existing workflows. It is absent from the SDK enum,
    so it is described as passed through rather than offered as a value
    to write.

The accompanying tests pin these descriptions to the SDK. Three enums
overlap without being interchangeable -- RAW_HCL is an IaC-input value
but not a policy one, TIRITH_JSON the reverse -- so a value documented
against the wrong enum points readers at something the attribute
rejects. Referencing the SDK constants directly means an upstream rename
breaks compilation rather than an assertion. One test fails deliberately
if the SDK starts accepting NO_CODE_JSON, so the caveat gets promoted
rather than quietly outliving its reason.

docs/ is generated from all three of these inputs, so they land together:
splitting them would leave intermediate commits whose generated output
did not match its sources, and docs-check would fail on each.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Updated various test files to replace hardcoded resource names with acctest.ResourceName for better uniqueness and consistency across tests.
- This change applies to stack templates, workflow templates, workflow groups, and workflow step templates.
- Ensures that resource names are generated dynamically, reducing potential conflicts in test environments.
- Introduced "Building this with AI" sections across various resource and guide documentation.
- Each section specifies the relevant AI skill to load and highlights common mistakes associated with the resource or guide.
- Created a script to automate the addition of these sections to ensure consistency and ease of updates.
@Akshat0694
Akshat0694 changed the base branch from docs/policy-and-navigation to fix/docs September 6, 2026 11:06
@hllvc
hllvc self-requested a review September 6, 2026 11:20
@akorohodstckg
akorohodstckg changed the base branch from fix/docs to main September 15, 2026 09:39
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