You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Write an OpenSpec change for the k6 Hub, starting from the merged feature brief. Follow the layout of openspec/changes/archive/2026-06-11-add-feature-flags/.
This issue is about the spec only. No Hub code, no resolver, no catalog repo. The output is proposal.md, design.md, tasks.md and the capability spec.md files, so the work can be reviewed and planned.
Proposed for the next core-team cycle.
Why now
The feature brief (docs/features/001-k6-hub.md, added in #6197) covers the problem, the desired state and what is out of scope, and per docs/features/README.md a merged brief is final. It says what changes for the user and why. It does not say how the catalog is modelled, how imports resolve, or what ships first.
Until that part is written down we can't estimate the work, split it across cycles, or decide what belongs in grafana/k6 and what belongs in a catalog repo. Feature flags went the same way: brief, then OpenSpec change, then implementation. The spec is where the tasks came from.
Scope
Create an OpenSpec change directory (working name openspec/changes/add-k6-hub/) with:
proposal.md - Why / What Changes / Capabilities (new and modified) / Impact / References.
design.md - context, goals and non-goals, domain model, numbered decisions including what each one was chosen over, risks and trade-offs.
specs/<capability>/spec.md - requirements in the ### Requirement: and #### Scenario: GIVEN/WHEN/THEN format the repo already uses. Testable, no implementation detail.
tasks.md - implementation split into chunks that fit a cycle.
Three things to work out while writing it, not before:
How to split the capabilities. The Hub is too big for one. Catalog data model and governance / import resolution / distribution and serving is one option, but whichever split we take needs an argument behind it. Feature flags was a single capability; this is larger.
Which side each requirement sits on. k6 side is the k6: URI, resolution, caching and failure modes. Catalog side is the schema, index generation, CODEOWNERS governance and the publishing flow. Decide whether both go in this change or only the k6 side.
What ships first. The brief describes the end state. The spec should say where the first delivery stops.
Out of scope
Implementation, prototypes, catalog content.
Reopening the brief. It is merged, so it is final. A change of direction means a new brief.
What the brief already excluded: removing the existing import syntaxes, bit-for-bit extension binary reproducibility, agent-facing tooling such as an MCP server or skills, and unifying how modules are authored across kinds.
Source material
Read in this order.
1. Feature brief - authoritative
Feature Brief (docs/features/001-k6-hub.md), once #6197 lands. Start here. Everything in the spec should trace back to it. Attached to this issue.
2 and 3. Historical documents - context only
A Product DNA and a Technical Spec, both written before the brief and never reviewed as a PR. Attached to this issue.
They are worth reading. There is a catalog schema, a resolution algorithm, a governance model and a hosting plan in there, and redoing all of that from scratch would be a waste. They are still not a spec to copy.
How to use them:
The brief supersedes them. It came out of reconsidering these two documents, so where they differ the call has already been made. What the brief dropped, such as private catalogs and npm/JSR packages, is out. What the brief added is in.
Treat their design decisions as options, not answers. Anything carried into design.md needs its own argument there, including what it beat.
They are older than the brief and say nothing about two of its requirements: reproducibility and machine-readable metadata.
What the brief leaves open
Not everything in the historical documents is still live, as above. What follows is the rest: points the brief states as a requirement without saying how, or does not mention at all. Each one needs a decision in design.md, or an open question written down.
#
Topic
What's open
1
Relationship to registry.k6.io
The brief has the Hub take over from today's extension catalog for provisioning. It does not say how we get there: whether registry.k6.io keeps serving during a transition, whether we generate a compatibility file for the current provisioning system (the Technical Spec generates extension-catalog.json), and when we switch.
2
Reproducibility and provenance
The brief wants each module version to map to an immutable commit that can be checked by digest, so a re-publish can't change a pinned or archived run. Nothing designs this yet. The historical documents rely on versions being immutable and on GPG-signed commits, which is a weaker promise. Needs a model: what gets digested, who checks it, and when.
3
Machine-readable metadata
The brief treats a queryable API as a core requirement: kind, versions, k6 compatibility, ownership, provenance. It needs defining - the shape, what we promise not to break, how it is served. The Technical Spec's @index.json is a start, but it is a build artifact for search rather than something callers can depend on.
4
Resolution mechanism
The brief describes behaviour, not mechanism. The Technical Spec picks esbuild for parse-time resolution based on an old reading of the JS runtime, so check that against Sobek as it is today. Either way the spec should describe what happens, not which library does it.
5
builtin version semantics
The brief settles the semantics: the version is whatever the binary ships, a constraint is matched against it, and a constraint that can't be met fails at load instead of quietly resolving to something else. How to model it is open. The Technical Spec uses a provides map on a core k6:@grafana/k6 module, and asks without answering whether that module is virtual.
6
Failure modes
None of the three documents cover these: Hub unreachable, constraints that can't all be satisfied, transitive imports that conflict, import cycles. The Product DNA says the resolver "must rigorously address" the last two, which is a requirement to write, not a design that exists.
7
package.json constraints
The brief does not mention manifests. Both historical documents let the manifest override import attributes (package.json > import attributes > latest) as a governance lever. Decide whether that is in the first spec.
Definition of done
The change directory exists with proposal.md, design.md, tasks.md and capability spec.md files, in the same format as the archived feature-flags change.
It passes whatever the OpenSpec tooling checks (openspec validate --strict if we use the CLI).
Every requirement traces back to the brief or to a decision recorded in design.md.
Every open point above is either decided in design.md or written down as an open question with an owner.
tasks.md is detailed enough to schedule across cycles and shows where the first delivery ends.
Product-DNA-k6-hub.md - historical, Google Drive export. Context only - not a specification, never PR-reviewed, superseded by the brief wherever they disagree.
Technical-Spec-k6-hub.md - historical, Google Drive export. Context only - its schema, resolution algorithm and governance model are options to re-argue in design.md, not decisions to adopt as-is.
Summary
Write an OpenSpec change for the k6 Hub, starting from the merged feature brief. Follow the layout of
openspec/changes/archive/2026-06-11-add-feature-flags/.This issue is about the spec only. No Hub code, no resolver, no catalog repo. The output is
proposal.md,design.md,tasks.mdand the capabilityspec.mdfiles, so the work can be reviewed and planned.Proposed for the next core-team cycle.
Why now
The feature brief (
docs/features/001-k6-hub.md, added in #6197) covers the problem, the desired state and what is out of scope, and perdocs/features/README.mda merged brief is final. It says what changes for the user and why. It does not say how the catalog is modelled, how imports resolve, or what ships first.Until that part is written down we can't estimate the work, split it across cycles, or decide what belongs in
grafana/k6and what belongs in a catalog repo. Feature flags went the same way: brief, then OpenSpec change, then implementation. The spec is where the tasks came from.Scope
Create an OpenSpec change directory (working name
openspec/changes/add-k6-hub/) with:proposal.md- Why / What Changes / Capabilities (new and modified) / Impact / References.design.md- context, goals and non-goals, domain model, numbered decisions including what each one was chosen over, risks and trade-offs.specs/<capability>/spec.md- requirements in the### Requirement:and#### Scenario:GIVEN/WHEN/THEN format the repo already uses. Testable, no implementation detail.tasks.md- implementation split into chunks that fit a cycle.Three things to work out while writing it, not before:
k6:URI, resolution, caching and failure modes. Catalog side is the schema, index generation, CODEOWNERS governance and the publishing flow. Decide whether both go in this change or only the k6 side.Out of scope
Source material
Read in this order.
1. Feature brief - authoritative
Feature Brief (
docs/features/001-k6-hub.md), once #6197 lands. Start here. Everything in the spec should trace back to it. Attached to this issue.2 and 3. Historical documents - context only
A Product DNA and a Technical Spec, both written before the brief and never reviewed as a PR. Attached to this issue.
They are worth reading. There is a catalog schema, a resolution algorithm, a governance model and a hosting plan in there, and redoing all of that from scratch would be a waste. They are still not a spec to copy.
How to use them:
npm/JSRpackages, is out. What the brief added is in.design.mdneeds its own argument there, including what it beat.What the brief leaves open
Not everything in the historical documents is still live, as above. What follows is the rest: points the brief states as a requirement without saying how, or does not mention at all. Each one needs a decision in
design.md, or an open question written down.registry.k6.ioregistry.k6.iokeeps serving during a transition, whether we generate a compatibility file for the current provisioning system (the Technical Spec generatesextension-catalog.json), and when we switch.@index.jsonis a start, but it is a build artifact for search rather than something callers can depend on.builtinversion semanticsprovidesmap on a corek6:@grafana/k6module, and asks without answering whether that module is virtual.package.jsonconstraintspackage.json> import attributes > latest) as a governance lever. Decide whether that is in the first spec.Definition of done
proposal.md,design.md,tasks.mdand capabilityspec.mdfiles, in the same format as the archived feature-flags change.openspec validate --strictif we use the CLI).design.md.design.mdor written down as an open question with an owner.tasks.mdis detailed enough to schedule across cycles and shows where the first delivery ends.Related issues and PRs
add-feature-flagsOpenSpec change (openspec/changes/archive/2026-06-11-add-feature-flags/) - the format and process precedent. It came out of proposal issue Proposal: Introduce a unified configuration option for experimental/preview features #4869.Attachments
All three documents are attached to this issue.
001-k6-hub.md- the feature brief. Authoritative; lands in the repo atdocs/features/001-k6-hub.mdwhen docs: add feature brief for k6 Hub unified module catalog #6197 merges.Product-DNA-k6-hub.md- historical, Google Drive export. Context only - not a specification, never PR-reviewed, superseded by the brief wherever they disagree.Technical-Spec-k6-hub.md- historical, Google Drive export. Context only - its schema, resolution algorithm and governance model are options to re-argue indesign.md, not decisions to adopt as-is.