docs: use typed primitives in the guard example and pin plugin installs - #171
Merged
Merged
Conversation
The declared-data guard example in docs/component.md was still built on static.NewBuilder and unstructured field access. That shape predates typed data cells: it was written for the old WithDataExtractor callback, where an unstructured object was the point, and the rewrite to cells and WithDataGuard kept the surrounding scaffolding rather than reshaping it. Every primitive package exports ExtractInto, WithDataGuard, and WithOptionalData, so nothing about declared data needs the unstructured variant. The example now uses a ConfigMap producer and a Deployment consumer, matching the configmap.ExtractInto snippet above it and the deployment.NewBuilder guard example below it, and it drops uns.NestedString and EditContent/SetNestedString in favour of cm.Data and EnsureContainerEnvVar. The unstructured version of the pattern remains in docs/primitives/unstructured.md, where the generic path is the subject. The README gains a team-install snippet for the ocf plugin. Consumers can commit extraKnownMarketplaces and enabledPlugins to their own .claude/settings.json and pin ref to the framework tag their go.mod requires, so the skills Claude reads describe the same API they compile against. A marketplace source accepts ref but not sha, so a release tag is the available pin; without it the marketplace tracks the default branch and the guidance drifts ahead of the pinned release. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01PnvBNAXNx7LZyyHR8ZamMU
There was a problem hiding this comment.
Pull request overview
Updates framework documentation to reflect the preferred “typed primitives + typed data cells” approach for declared-data guards, and documents how consumers can pin the Claude Code plugin marketplace reference to the same framework release they build against.
Changes:
- Rewrites the “Blocking on declared data” guard example to use
configmap.NewBuilder/deployment.NewBuilder, typed extraction (cm.Data["endpoint"]), and typed workload mutation (EnsureContainerEnvVar). - Adds a README snippet showing how to commit
.claude/settings.jsonwithextraKnownMarketplaces+enabledPlugins, pinningrefto a release tag. - Regenerates the plugin reference mirror for
component.mdso it matchesdocs/component.md.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| README.md | Adds a team-shareable Claude Code plugin install snippet with ref pinned to a framework release tag. |
| docs/component.md | Updates the declared-data guard example to use typed primitives and typed field access/mutation. |
| plugin/skills/building-components/references/component.md | Regenerated reference copy of docs/component.md reflecting the updated guard example. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The declared-data guard example in
docs/component.mdwas still written againststatic.NewBuilderand unstructuredfield access, which made the generic primitive look like the way to do declared data. It isn't: the shape predates typed
data cells, and the rewrite to cells and
WithDataGuardkept the old scaffolding instead of reshaping the example. Thisswaps it for typed primitives and, separately, adds a README snippet so consumers can pin the
ocfClaude Code pluginto the framework version they compile against.
Changes
Blocking on declared dataexample indocs/component.mdnow uses a ConfigMap producer and a Deploymentconsumer. It reads
cm.Data["endpoint"]instead ofuns.NestedString, and injects the value withEnsureContainerEnvVarinstead ofEditContentplusSetNestedString. This matches theconfigmap.ExtractIntosnippet directly above it and the
deployment.NewBuildercustom-guard example directly below it.README.mdgains a team-install snippet for the plugin:extraKnownMarketplacesplusenabledPluginscommitted to aconsumer's own
.claude/settings.json, withrefpinned to a framework release tag so the skills Claude readsdescribe the same API the project builds against.
plugin/skills/building-components/references/component.mdis regenerated viamake sync-plugin.No
pkg/code changed, so this is documentation only.Challenges
The unstructured shape wasn't arbitrary, which is why it survived a rewrite. It came in with the guard docs when the
extraction API was still
WithDataExtractor(func(obj uns.Unstructured) error), where reaching into arbitrary JSON wasthe whole point. Once extraction became typed cells, the justification went away but the code didn't. All 25 primitive
packages export
ExtractInto,WithDataGuard, andWithOptionalData, so the typed rewrite needed no API changes.For the plugin pin, Claude Code distinguishes a marketplace source from a plugin source: the marketplace source that
extraKnownMarketplacesconfigures acceptsref(branch or tag) but notsha. A release tag is therefore the pin thatis actually available, and the README says so rather than suggesting a commit pin that would be silently ignored.
Testing
The rewritten example was compiled against the real API in a throwaway package under the module before being committed,
so the builder, mutator, and
ExtractIntosignatures are verified rather than assumed; the package was deletedafterwards. The README's JSON snippet validates under
jq.make fmt-mdreports both files unchanged, andmake sync-pluginwas re-run so the plugin reference mirror matchesdocs/.Reviewers may want to check one judgment call I left alone:
plugin/skills/structuring-operators/SKILL.mdalso usesstatic.NewBuilder, but there the resource is a third-party cloud-provider CR with no typed primitive, so theunstructured builder looks correct rather than accidental.
docs/primitives/unstructured.md,docs/custom-resource.md, andexamples/custom-resource/keep their unstructured usage for the same reason: thegeneric path is their subject.
🤖 Generated with Claude Code
https://claude.ai/code/session_01PnvBNAXNx7LZyyHR8ZamMU