Skip to content
Security
Skill

/authoring-service-schema

Author or edit a Dogwood SERVICE schema — the event schema (.dwschema: event kinds, decision vs history points, renamed/reserved fields, nested records, correlation pins) and/or information providers (providers.json + the Rhai `evaluate` implementation behind a computed

From plugin
dogwood
2584 skills
Install
$ npx -y skills add dogwood-policy/dogwood --skill authoring-service-schema --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/authoring-service-schema

Context preview

The summary Claude sees to decide when to auto-load this skill.

Author or edit a Dogwood SERVICE schema — the event schema (.dwschema: event kinds, decision vs history points, renamed/reserved fields, nested records, correlation pins) and/or information providers (providers.json + the Rhai `evaluate` implementation behind a computed

SKILL.md

authoring-service-schema.SKILL.md
name: authoring-service-schema
description: "Author or edit a Dogwood SERVICE schema — the event schema (.dwschema: event kinds, decision vs history points, renamed/reserved fields, nested records, correlation pins) and/or information providers (providers.json + the Rhai `evaluate` implementation behind a computed guardrail fact). Use when a policy needs a non-default event model (a history-only event kind, a renamed principal field, a pin/correlation invariant) or a computed fact from a provider/guardrail. The service schema is OPTIONAL and defaults sensibly (default = request/response/error kinds with only `request` deciding, a universal principal pin giving key-local semantics, a 24h `max_window` cap, no providers, and a small standard macro library), so this also covers deciding whether one is even needed. Requires a Cedar action schema first — that is authoring-action-schema. NOT for the Cedar action schema itself (entities/actions/context) — that is authoring-action-schema. NOT for writing `.dw` policies — that is autoformalize-policies."

Authoring a Dogwood service schema (events + providers)

Your job: produce the **service-schema half** of a Dogwood schema — an **event schema** (`.dwschema`) and/or an **information-provider declarations** file (`providers.json` plus its Rhai implementation) — that parses, is well-formed, and lets the policies you care about validate against a concrete action schema.

The service schema is **entirely optional and defaults sensibly**. The default event schema declares three kinds — `request` (the only decision kind), `response`, and `error` (both history-only) — each carrying the action's inputs (`response` also its outputs) plus the reserved leaves `callerPrincipal` / `callerResource` / `requestId` / `sessionId`. Crucially, `callerPrincipal` is a **universal symmetric pin** (`pin callerPrincipal: principalType(A) = principal` on every kind), so the default runs under **key-local semantics**: every temporal predicate is silently correlated to the current request's principal, and other principals' events are invisible to it. The default look-back cap is `max_window = 24h`, the default provider set is **empty**, and the default macro library is the small standard one (`count_within`, `sum_within`, `count_distinct_within`, `bind`). So the most important decision is Step 0: *do you even need one?* If not, the best service schema is no service schema — omit it and Dogwood uses the default.

This skill has two cores — **events** and **providers** — plus **macros** as a related seam (Step 3, briefly; the guide owns it). Do **not** invent DSL or JSON from memory: the guide is exhaustive and every construct is corpus-verified. Follow the steps in order.

Step 0 — Decide whether you need a service schema at all (do this first)

Write a custom **event schema** only if the application's event model diverges from the default request/response/error model in one of these ways:

  • **A history-only event kind the default lacks** — an `audit`/`outcome` kind, or

renaming the set (`attempt`/`outcome` instead of `request`/`response`). The default already gives `request` (decision) + `response` + `error` (history); customize only to go *beyond* that.

  • **A different decision point** — some kind other than `request` must run

authorization (mark it `decision`).

  • **A renamed or extra reserved/principal field** — the injected principal is

`actor` not `callerPrincipal`, or an extra `__session_id`.

  • **Nested record fields** — hierarchical fields like `__platform.session.id`.
  • **A different pin / correlation invariant** — the default already pins

`callerPrincipal` on every kind (key-local, per-principal semantics). Write a custom schema to pin a *different* key (a session id), to add an extra pin, or — going the other way — to get **global-trace semantics** (a policy about *any* principal's events, e.g. "N logins by any user"), which requires a schema *without* the universal principal pin (the shipped `configuration/event-schemas/unpinned.dwschema` is exactly that).

  • **A longer look-back than 24h** — every temporal window is capped by the

event schema's `max_window` directive, **24h when absent**, so a policy with `within 7d` is a validation error under the default. Raising the cap is an event-schema change: copy the default schema and add `max_window = <interval>` (e.g. `max_window = 30d`) at the top of the file. **A `.dwschema` containing only the directive declares zero events** — it passes the isolated `schema event` check but every policy predicate then fails the composite `validate` (`does not name a declared event`) — so always carry the event declarations along with the directive.

Write **providers** (`providers.json`) only if a policy needs a **computed fact** not in the request — a regex match, denylist check, risk/content score, allowlist lookup — i.e. the `Provider::Name(args)` / `guardrails { }` path. Write a **macro library** only for a genuinely reusable policy fragment (Step 3).

If **none** of these apply, **skip the service schema entirely** — do not write an empty `.dwschema` (an explicitly-supplied blank event schema declares zero events and is *rejected* at build time; only *omitting* it falls back to the default). Say so and stop.

The ground truth (read before authoring)

The event-schema DSL and the provider declaration format are precisely documented, including their legality rules. Treat these as authoritative. Paths are relative to this skill directory (`.claude/skills/authoring-service-schema/`); the guide lives in the `dogwood-docs` crate:

  • `../../../dogwood-docs/guide/03-event-schema.md` — the **event-schema DSL**:

the `[decision] event <A>::kind { … }` shape, the four selectors (`inputs`, `outputs`, `principalType`, `resourceType`), spreads vs field-types, nested records, **pins** (`pin name: type = <request-reference>`), decision vs history kinds, the **`max_window` directive

Read more
Ships withdogwood

Dogwood is a governance language designed for AI agents and their tools. It supports Cedar policies and adds temporal conditions (since, formerly, once, aggregations) to look back over an agent's recent events.

Get the whole plugin
Stats
334
Stars
22
Forks
Active
Maintenance
Rust
Language
Apache-2.0
License
6d ago
Last commit
21d ago
Created

Repo: dogwood-policy/dogwood