From 07f970c98f83fe54318dd0151639f58417c0a871 Mon Sep 17 00:00:00 2001 From: c2thorn Date: Fri, 10 Jul 2026 14:04:14 -0500 Subject: [PATCH 1/6] Seed the agent knowledge base .agents/knowledge/: an index routing to the contributor docs plus agent-only entries for judgment the docs don't cover. First entry: the Enum-vs-String trade-off (promoted from schema-review, which now references it). BACKLOG.md lists candidate entries by docs-coverage. AGENTS.md and the three workflows point agents at the index. --- .agents/knowledge/BACKLOG.md | 27 +++++++++ .agents/knowledge/README.md | 44 +++++++++++++++ .agents/knowledge/field/enums-vs-strings.md | 36 ++++++++++++ .agents/knowledge/index.md | 56 +++++++++++++++++++ .agents/skills/utils/schema-review/SKILL.md | 14 ++--- .../workflows/add_list_resource/SKILL.md | 2 + .agents/skills/workflows/default/SKILL.md | 1 + .../skills/workflows/new_resource/SKILL.md | 1 + AGENTS.md | 5 +- 9 files changed, 174 insertions(+), 12 deletions(-) create mode 100644 .agents/knowledge/BACKLOG.md create mode 100644 .agents/knowledge/README.md create mode 100644 .agents/knowledge/field/enums-vs-strings.md create mode 100644 .agents/knowledge/index.md diff --git a/.agents/knowledge/BACKLOG.md b/.agents/knowledge/BACKLOG.md new file mode 100644 index 000000000000..252ae12c011b --- /dev/null +++ b/.agents/knowledge/BACKLOG.md @@ -0,0 +1,27 @@ +# Knowledge backlog + +Candidate agent-only entries, grouped by contributor-docs coverage. Each lands as its own reviewed PR. + +## Not in the docs + +- **casing-and-pluralization** — how API names map to Terraform names; when `api_name` is required. +- **output-only-test-assertions** — server-populated fields must have their values asserted in tests. +- **pr-mined-lessons** — recurring review catches and per-service quirks surfaced from merged PRs. + +## Overlaps the docs (entry would add the judgment layer) + +- **permadiff-decision-path** — choosing between `output`, `default_from_api`, diff suppression, or a real + fix; mechanics are in `docs/content/develop/diffs.md`. +- **data-source-idioms** — pitfalls beyond the procedure in `docs/content/develop/add-handwritten-datasource.md`. +- **test-adequacy-traps** — cases `docs/content/test/test.md` doesn't cover (identical-config update steps, + missing import-and-recheck). + +## Mostly covered by the docs (revisit only if agents misread them) + +- **immutability-nuances** — `docs/content/reference/field.md`, `docs/content/best-practices/immutable-fields.md`. +- **sensitive-and-write-only** — `docs/content/reference/field.md`. + +## Lives elsewhere + +- **failure-troubleshooting-catalog** — `.agents/skills/operations/troubleshooting_reference.md`; migrates + here if it outgrows the skill. diff --git a/.agents/knowledge/README.md b/.agents/knowledge/README.md new file mode 100644 index 000000000000..fd87059ef795 --- /dev/null +++ b/.agents/knowledge/README.md @@ -0,0 +1,44 @@ +# Agent knowledge base + +The **funnel to the knowledge an agent needs**: [`index.md`](index.md) routes to the right source for a +given decision. Agents read the index at decision points and open only what the task needs — never the +whole base (loading everything degrades reasoning and wastes context). + +Most knowledge already lives in the **contributor documentation** (`docs/content/`), and that stays the +single source of truth for everything it covers — the index points there. **Agent-only entries** exist in +this directory only for knowledge that has no home in the docs: judgment rules that were never written +down, pitfall catalogs, and (later) lessons proposed by agents from completed tasks. If something is +covered by the contributor docs but covered badly, the fix is improving the docs — not writing a copy here. + +Planned entries: [`BACKLOG.md`](BACKLOG.md). + +## Entry format + +One Markdown file, one topic, ≤120 lines, YAML frontmatter: + +```yaml +--- +name: enums-vs-strings # kebab-case, unique, matches filename +description: Model an API enum as Enum (strict) or String (forward-compatible). # the index line; <=140 chars +topics: [field] # index section(s) that list it +task_types: [field-add, new-resource] +source: docs/content/best-practices/validation.md # provenance: doc, PR, or "authored" +status: certified # certified (human-reviewed) | draft (proposed, unreviewed) +last_verified: 2026-07-09 +--- +``` + +Body rules: **rule + the why**, never bare imperatives; a real example per rule; a "do NOT use for" line +where misuse is likely; reference the contributor docs rather than duplicating them. + +## Curation rules + +- **Nothing enters unreviewed.** Entries land via PR like code, **one entry at a time** — each one codifies + team judgment and deserves a real review conversation. Agent-proposed entries ship as `status: draft` in + the task PR that motivated them; a human review flips them to `certified`. +- **Never bulk-rewrite.** Edit entry by entry. Do not have a model re-summarize or reorganize the base + wholesale — that is the documented failure mode (drift and self-contradiction). +- **Contradictions are quarantined.** A proposed entry that contradicts an existing one is not merged; a + human adjudicates: update or retire the old entry, or discard the proposal. +- **Keep the index true.** Index lines come from entry frontmatter (name + description). Adding or changing + an entry updates the index in the same commit. diff --git a/.agents/knowledge/field/enums-vs-strings.md b/.agents/knowledge/field/enums-vs-strings.md new file mode 100644 index 000000000000..12d0973b3df3 --- /dev/null +++ b/.agents/knowledge/field/enums-vs-strings.md @@ -0,0 +1,36 @@ +--- +name: enums-vs-strings +description: Model an API enum as Enum (strict, plan-time) or String (forward-compatible) - the deliberate trade-off. +topics: [field] +task_types: [field-add, new-resource] +source: docs/content/best-practices/validation.md + the schema-review skill's original trade-off note +status: draft +last_verified: 2026-07-09 +--- + +# Enum vs. String + +**The trade-off (decide deliberately, per field):** +- **`Enum`** when the value set is exhaustive for a clearly-defined domain and new values are extremely + unlikely. Buys strict plan-time validation — users fail fast instead of mid-apply. +- **`String`** (with allowed values named in the description and a link to API docs) when the API is + likely to add values. **Why:** an Enum's value list lives in the provider; when the API adds a value, + every user needs a provider upgrade before they can use it — and imports of resources using the new + value break. A String stays forward-compatible. + +```yaml +- name: 'severity' + type: Enum + enum_values: + - 'LOW' + - 'MEDIUM' + - 'HIGH' +``` + +**Rules for Enum:** +- Do **not** include `UNSPECIFIED`-style values in `enum_values`. +- Enums validate against the list automatically; a custom `validation` **overrides** that default — if you + add one, it must re-verify the enum values itself. + +**Rule for String-instead-of-enum:** list the allowed values in the field description with a link to the +API docs — otherwise users only discover an invalid value when the API rejects it mid-apply. diff --git a/.agents/knowledge/index.md b/.agents/knowledge/index.md new file mode 100644 index 000000000000..f50151f54a7c --- /dev/null +++ b/.agents/knowledge/index.md @@ -0,0 +1,56 @@ +# Knowledge index + +Read this index at decision points; open only the source the task needs. Format and curation rules: +[README.md](README.md). + +## Contributor documentation (`docs/content/`) + +**Reference (what the schema properties mean):** + +- Field properties (`output`, `immutable`, defaults, `sensitive`, validation, enums, arrays, `api_name`, conflicts) — `docs/content/reference/field.md` +- Resource-level properties (URLs, timeouts, async, custom code hooks) — `docs/content/reference/resource.md` +- Resource metadata — `docs/content/reference/metadata.md` +- Samples format — `docs/content/reference/sample.md` +- Update test expectations — `docs/content/reference/update-test-changes.md` +- Make commands — `docs/content/reference/make-commands.md` + +**Procedures (how to do a task):** + +- Add or change a field — `docs/content/develop/add-fields.md` +- Add a resource — `docs/content/develop/add-resource.md` +- Add a handwritten data source — `docs/content/develop/add-handwritten-datasource.md` +- Add IAM support — `docs/content/develop/add-iam-support.md` +- Custom code (expanders, flatteners, hooks) — `docs/content/develop/custom-code.md` +- Fix diffs and permadiffs — `docs/content/develop/diffs.md` +- Client-side fields — `docs/content/develop/client-side-fields.md` +- Promote beta → GA — `docs/content/develop/promote-to-ga.md` +- Generate the providers / set up the environment — `docs/content/develop/generate-providers.md`, `docs/content/develop/set-up-dev-environment.md` + +**Testing:** + +- Write acceptance tests (create, update, import) — `docs/content/test/test.md` +- Run tests — `docs/content/test/run-tests.md` + +**Contributing (PRs, review, release notes):** + +- Contribution process end to end — `docs/content/contribution-process.md` +- Create a PR — `docs/content/code-review/create-pr.md` +- Write release notes — `docs/content/code-review/release-notes.md` +- Review a PR — `docs/content/code-review/review-pr.md` + +**Documentation:** + +- Add resource documentation — `docs/content/document/add-documentation.md` +- Handwritten docs style guide — `docs/content/document/handwritten-docs-style-guide.md` + +**Best practices (judgment calls with team positions):** + +- Immutable fields / ForceNew — `docs/content/best-practices/immutable-fields.md` +- Deletion policy — `docs/content/best-practices/deletion-policy.md` +- Labels and annotations — `docs/content/best-practices/labels-and-annotations.md` +- Client-side validation — `docs/content/best-practices/validation.md` +- Common resource patterns (singletons) — `docs/content/best-practices/common-resource-patterns.md` + +## Agent-only entries + +- **enums-vs-strings** — Model an API enum as Enum (strict, plan-time) or String (forward-compatible): the deliberate trade-off. — [field/enums-vs-strings.md](field/enums-vs-strings.md) diff --git a/.agents/skills/utils/schema-review/SKILL.md b/.agents/skills/utils/schema-review/SKILL.md index b04676cfa6ea..e69735b16883 100644 --- a/.agents/skills/utils/schema-review/SKILL.md +++ b/.agents/skills/utils/schema-review/SKILL.md @@ -1,6 +1,6 @@ --- name: schema-review -description: "Stub skill for reviewing Magic Modules schemas. Currently covers Enum vs. String trade-offs." +description: "Skill for reviewing Magic Modules schemas. Currently covers the Enum vs. String decision via the knowledge base." --- # `schema-review` @@ -14,17 +14,11 @@ description: "Stub skill for reviewing Magic Modules schemas. Currently covers E ## Execution Steps ### 1. Enum vs. String Trade-off -When adding a field that is defined as an Enum in the API, you must decide between `Enum` and `String` in Magic Modules. - -#### The Trade-off: -* **Prefer `Enum`** when you want strict, plan-time validation of values to fail fast. -* **Prefer `String`** (with allowed values documented) when the API is dynamic or likely to add values. This prevents Terraform from crashing with a validation error for users when the API updates *before* the provider catches up. +When adding a field that is defined as an Enum in the API, you must decide between `Enum` and `String` in Magic Modules. Read the knowledge entry [.agents/knowledge/field/enums-vs-strings.md](../../../knowledge/field/enums-vs-strings.md) and apply its trade-off. > [!NOTE] -> This skill is a **stub** and will be expanded over time with more schema review checklist items (such as `api_name` overrides, array flattening, output-only fields, etc.). +> This skill will be expanded over time with more schema review checklist items. The judgment content lives in [.agents/knowledge/](../../../knowledge/index.md) — this skill references it and does not hold its own copy. ### 2. Verification & Handoff -Instructions on how the agent should verify the command succeeded, and what workflow or rule it should return to next. -* Proceed with your field addition or PR review based on this stylistic choice. -* Reference the `modernization_roadmap.md` for upcoming expansions to this checklist. +* Proceed with your field addition or PR review based on the decision. diff --git a/.agents/skills/workflows/add_list_resource/SKILL.md b/.agents/skills/workflows/add_list_resource/SKILL.md index 28602c8045ea..4336384df9d3 100644 --- a/.agents/skills/workflows/add_list_resource/SKILL.md +++ b/.agents/skills/workflows/add_list_resource/SKILL.md @@ -9,6 +9,8 @@ description: "Opt resource into MMv1 list-resource generation by setting `genera This workflow produces a single PR scoped to **one product** that flips `generate_list_resource: true` on every eligible MMv1 resource in that product, generates the downstream code, runs the generated list-query tests, and opens the PR. Do **one product per PR**, with as many eligible resources as pass. +Consult `.agents/knowledge/index.md` for the topics this task touches and open the relevant sources. + ## Prerequisites * You are in the `magic-modules` root directory. diff --git a/.agents/skills/workflows/default/SKILL.md b/.agents/skills/workflows/default/SKILL.md index 3aeff1256696..906348cecff1 100644 --- a/.agents/skills/workflows/default/SKILL.md +++ b/.agents/skills/workflows/default/SKILL.md @@ -14,6 +14,7 @@ This document outlines the structured 5-step lifecycle for formal implementation ### 2. Triage * Gather context on the change or bug. Plan the change (New feature or bug fix) within schema or logic. +* Consult `.agents/knowledge/index.md` for the topics the change touches and open the relevant sources. * Execute the `triage` skill (located in `.agents/skills/operations/triage/`) to perform this work. * **Transfers to Step 3:** Approved implementation plan and file paths file. diff --git a/.agents/skills/workflows/new_resource/SKILL.md b/.agents/skills/workflows/new_resource/SKILL.md index a9d631bc89c2..f5f0d8da2a7d 100644 --- a/.agents/skills/workflows/new_resource/SKILL.md +++ b/.agents/skills/workflows/new_resource/SKILL.md @@ -31,5 +31,6 @@ There are two ways to generate the initial YAML definition for the resource: - If the subagent reports test failures, enter the **Default Workflow** ([default/SKILL.md](../default/SKILL.md)) at **Step 5 (Fix)** to plan remediation. ### 2B. Manual Path +* Consult `.agents/knowledge/index.md` for the topics the resource touches and open the relevant sources. * Follow the standard process to draft the YAML definition in `mmv1/products/...` based on API documentation and repository patterns. * **Handoff:** Once the YAML is drafted, enter the **Default Workflow** ([default/SKILL.md](../default/SKILL.md)) at **Step 3 (Generate)** to compile the provider and continue with testing. diff --git a/AGENTS.md b/AGENTS.md index 57bdac73fe33..e582a507bbcc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -12,8 +12,9 @@ here, upstream — never in the downstream repos. provider task. - **`.agents/skills/`** — reusable skills the workflows compose (generation, testing, log parsing, troubleshooting). Each skill's `SKILL.md` frontmatter states when to use it. -- **`.agents/knowledge/`** — the curated knowledge base (initial seeding in progress). When present, - consult its `index.md` at decision points and open only the entries the task needs. +- **[.agents/knowledge/index.md](.agents/knowledge/index.md)** — the knowledge index: a short map of + where provider knowledge lives. Consult it at the start of any task; open only the sources the task + needs. - **`.agents/archive/`** — parked tracks (currently TGC). Not maintained; do not use as reference. ## Ground rules From 315dc75c554ce92346b8bab451bf9a3d6bb04548 Mon Sep 17 00:00:00 2001 From: Cameron Thornton Date: Fri, 10 Jul 2026 15:11:02 -0500 Subject: [PATCH 2/6] tighten index reading instructions --- AGENTS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index e582a507bbcc..ff6e1b15a68b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,8 +13,8 @@ here, upstream — never in the downstream repos. - **`.agents/skills/`** — reusable skills the workflows compose (generation, testing, log parsing, troubleshooting). Each skill's `SKILL.md` frontmatter states when to use it. - **[.agents/knowledge/index.md](.agents/knowledge/index.md)** — the knowledge index: a short map of - where provider knowledge lives. Consult it at the start of any task; open only the sources the task - needs. + where provider knowledge lives. **CRITICAL:** At the start of any session or conversation, you MUST + first open and read this file to check for relevant patterns or instructions before taking any other action. - **`.agents/archive/`** — parked tracks (currently TGC). Not maintained; do not use as reference. ## Ground rules From a2c2734b3395e6519da621de55648d469cbe30d5 Mon Sep 17 00:00:00 2001 From: Cameron Thornton Date: Fri, 10 Jul 2026 15:17:50 -0500 Subject: [PATCH 3/6] upgrade to a rule --- .agents/rules/general.md | 10 ++++++++++ AGENTS.md | 3 +-- 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 .agents/rules/general.md diff --git a/.agents/rules/general.md b/.agents/rules/general.md new file mode 100644 index 000000000000..e3b5d0b7f56c --- /dev/null +++ b/.agents/rules/general.md @@ -0,0 +1,10 @@ +--- +trigger: always_on +description: Mandatory starting action to read the knowledge index at the beginning of each session. +--- + +# General Rules + +## 1. Mandatory Starting Action +- **Rule:** At the start of any session or conversation, you MUST first open and read the Knowledge Index file ([.agents/knowledge/index.md](.agents/knowledge/index.md)) before taking any other action or starting any research/implementation. +- **Purpose:** To check for relevant patterns, guides, or workspace-specific instructions. \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index ff6e1b15a68b..c14048d0d345 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,8 +13,7 @@ here, upstream — never in the downstream repos. - **`.agents/skills/`** — reusable skills the workflows compose (generation, testing, log parsing, troubleshooting). Each skill's `SKILL.md` frontmatter states when to use it. - **[.agents/knowledge/index.md](.agents/knowledge/index.md)** — the knowledge index: a short map of - where provider knowledge lives. **CRITICAL:** At the start of any session or conversation, you MUST - first open and read this file to check for relevant patterns or instructions before taking any other action. + where provider knowledge lives. Refer to this to check for relevant patterns or instructions. - **`.agents/archive/`** — parked tracks (currently TGC). Not maintained; do not use as reference. ## Ground rules From dced8a6a1b9946d90de9845be01ac8f26d7ea415 Mon Sep 17 00:00:00 2001 From: c2thorn Date: Fri, 10 Jul 2026 15:23:00 -0500 Subject: [PATCH 4/6] Add raw-config-access to the knowledge backlog --- .agents/knowledge/BACKLOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.agents/knowledge/BACKLOG.md b/.agents/knowledge/BACKLOG.md index 252ae12c011b..a8b0be590fa3 100644 --- a/.agents/knowledge/BACKLOG.md +++ b/.agents/knowledge/BACKLOG.md @@ -7,6 +7,9 @@ Candidate agent-only entries, grouped by contributor-docs coverage. Each lands a - **casing-and-pluralization** — how API names map to Terraform names; when `api_name` is required. - **output-only-test-assertions** — server-populated fields must have their values asserted in tests. - **pr-mined-lessons** — recurring review catches and per-service quirks surfaced from merged PRs. +- **raw-config-access** — when to use `d.GetRawConfig()` / `GetRawPlan()` / `GetRawState()` instead of + `Get`/`GetOk`, which conflate "unset in config" with "set to the zero value" (false/0/""); the raw cty + values distinguish null from zero for detecting whether a user actually set a field. ## Overlaps the docs (entry would add the judgment layer) From 9d1ab631ef3eb0400ccc6561588b7f8eb9f513d0 Mon Sep 17 00:00:00 2001 From: c2thorn Date: Fri, 10 Jul 2026 15:55:54 -0500 Subject: [PATCH 5/6] Address review: FIELD_NAME_UNSPECIFIED wording; drop output-only-assertions from backlog --- .agents/knowledge/BACKLOG.md | 1 - .agents/knowledge/field/enums-vs-strings.md | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.agents/knowledge/BACKLOG.md b/.agents/knowledge/BACKLOG.md index a8b0be590fa3..9448f6602794 100644 --- a/.agents/knowledge/BACKLOG.md +++ b/.agents/knowledge/BACKLOG.md @@ -5,7 +5,6 @@ Candidate agent-only entries, grouped by contributor-docs coverage. Each lands a ## Not in the docs - **casing-and-pluralization** — how API names map to Terraform names; when `api_name` is required. -- **output-only-test-assertions** — server-populated fields must have their values asserted in tests. - **pr-mined-lessons** — recurring review catches and per-service quirks surfaced from merged PRs. - **raw-config-access** — when to use `d.GetRawConfig()` / `GetRawPlan()` / `GetRawState()` instead of `Get`/`GetOk`, which conflate "unset in config" with "set to the zero value" (false/0/""); the raw cty diff --git a/.agents/knowledge/field/enums-vs-strings.md b/.agents/knowledge/field/enums-vs-strings.md index 12d0973b3df3..8c7bdc5fe66b 100644 --- a/.agents/knowledge/field/enums-vs-strings.md +++ b/.agents/knowledge/field/enums-vs-strings.md @@ -28,7 +28,9 @@ last_verified: 2026-07-09 ``` **Rules for Enum:** -- Do **not** include `UNSPECIFIED`-style values in `enum_values`. +- Omit the `FIELD_NAME_UNSPECIFIED` value from `enum_values` — it is the proto convention's first enum + value, representing 0/unset, not a real choice. An enum whose meaningful values include a literal + `UNSPECIFIED` (e.g. BackendService) keeps it. - Enums validate against the list automatically; a custom `validation` **overrides** that default — if you add one, it must re-verify the enum values itself. From 0093f6d6a0030ac3ab62c0d5c2e1df1e58ebf1e5 Mon Sep 17 00:00:00 2001 From: c2thorn Date: Fri, 10 Jul 2026 16:02:43 -0500 Subject: [PATCH 6/6] Trim UNSPECIFIED note to the general rule --- .agents/knowledge/field/enums-vs-strings.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.agents/knowledge/field/enums-vs-strings.md b/.agents/knowledge/field/enums-vs-strings.md index 8c7bdc5fe66b..f01ff36e378c 100644 --- a/.agents/knowledge/field/enums-vs-strings.md +++ b/.agents/knowledge/field/enums-vs-strings.md @@ -29,8 +29,7 @@ last_verified: 2026-07-09 **Rules for Enum:** - Omit the `FIELD_NAME_UNSPECIFIED` value from `enum_values` — it is the proto convention's first enum - value, representing 0/unset, not a real choice. An enum whose meaningful values include a literal - `UNSPECIFIED` (e.g. BackendService) keeps it. + value, representing 0/unset, not a real choice. - Enums validate against the list automatically; a custom `validation` **overrides** that default — if you add one, it must re-verify the enum values itself.