What the specification is
dagstack/plugin-system-spec is the normative source of truth. It pins down what every plugin-system implementation (for Python, TypeScript, Go and any future language) MUST contain — and why it is so, rather than otherwise. Concrete implementations (plugin-system-python, plugin-system-typescript, plugin-system-go) MUST honour this contract and demonstrate compliance via a shared set of conformance tests.
How the "Specification" section differs from the guides
| Section | Audience | What it gives you |
|---|---|---|
| Concepts | Plugin-system user | Explains how the registry, manifest and dispatcher work today, applied to a specific language. |
| Guides | Plugin-system user | Walks through a task step by step (write a plugin, configure it). |
| Specification (this section) | Implementation author / author of a new plugin kind / reviewer | Explains why a decision was made; pins the normative guarantees you can rely on; describes which situations every binding MUST handle the same way regardless of language. |
If you are writing a plugin for Python or TypeScript, read "Concepts" and "Guides". If you are:
- implementing your own binding for a new language;
- designing your own plugin kind (hookspec) and want it to work across all languages;
- taking part in an architectural review of core changes;
then this section is for you.
How ADRs differ from ordinary documentation
An ADR (Architecture Decision Record) is a short document that captures one architectural decision:
- Context — which problem is being solved, and what made it hard to solve before.
- Decision — what is being done and by which means.
- Consequences — what becomes easier / harder / impossible after this decision.
- Alternatives — which options were considered and why they were rejected.
An ADR is a historical artefact. When a decision is revisited the ADR is not deleted — a new ADR appears that supersedes the previous one. This makes it possible to trace the evolution of the architecture and to understand the rationale behind the current state.
The six plugin-system ADRs
As of v1.0 the specification pins six decisions:
- ADR-0001: Core architecture — what a plugin, manifest, registry and context are. The shared structure of every implementation.
- ADR-0002: Hook invocation semantics — five dispatch classes (singleton / broadcast-collect / broadcast-notify / chain / capability) and their normative behaviour.
- ADR-0003: Orchestration-neutral runtime — the eight runtime invariants that make a plugin behave identically under FastAPI, Dagster, Celery and pytest.
- ADR-0004: Hookspec formalism — how a plugin-kind contract is described via YAML + JSON Schema, from which per-language types are emitted.
- ADR-0005: Horizontal extensions — governance, quota and observability layered on top of any user plugin.
- ADR-0006: File-based discovery — how, exactly, the registry locates plugins on the filesystem.
Normative vs descriptive text
The pages in this section are a descriptive English-language synopsis of each ADR. They translate the formal contract into accessible prose and add cross-language examples.
The formal normative text of every ADR lives in the spec repository dagstack/plugin-system-spec. Every page in this section has a direct link to the full text of the corresponding ADR. If you are preparing a change to a binding, read the normative version: that is where every edge case, every forbidden construction and every error-message requirement is pinned down.
How the specification is changed
If you want to change plugin-system behaviour (add a sixth dispatch class, relax an invariant, change the manifest format):
- Open an issue in
dagstack/plugin-system-specdescribing the problem and the proposed solution. - After discussion, raise a PR with a new ADR (
ADR-0007+) or a revision of an existing one (with an explicitsupersedes). - Pass architect review and review by the maintainers of the implementations — every
plugin-system-<lang>MUST confirm that the proposal can be implemented. - After merge, update the implementations and refresh the corresponding synopsis in this section (in the same spec-repo PR, so that drift cannot creep in).
Related specifications
dagstack/config-spec— the plugin system uses the config stack to read per-plugin sections (<kind>.<name>).dagstack/logger-spec— structured logging exposed viaPluginContext.logger.dagstack/tenancy-spec—TenantContextis delivered throughPluginContextfor multi-tenant isolation.
A decision-by-decision relationship table is on the Cross-spec relationships page.