Reference · som-skill-library
Skills
SOM carries context; Skills carry knowledge. A skill is a rule written once, by editorial, readable by every tool. It declares what is true — the tool that owns the executor is the only thing that acts.
The model
Skills declare. Executors act.
The skill declares
A skill file states a condition and what is true when it holds — a flag stands, a hold applies, an enrichment is warranted. It never runs anything, never writes story state, and never changes content.
The executor recalls
Executors live inside vendor tools. Each matches incoming messages against skill adverts — the machine-read recall block — and publishes what the skill declares as skill.warning.raised.
The tool acts
The MAM keeps a held asset uncommittable, playout refuses the take, the CMS holds one path. Each in its own way, and each deciding for itself. Nothing is sent a command.
Open shape, house policy. Skills follow the open agentskills.io ↗ format: a markdown file with YAML frontmatter. The shared library is generic; a newsroom loads its own values against it. Your policy stays yours, and a newsroom can implement SOM 1.0 completely without using the library at all.
Anatomy
One file: frontmatter for machines, prose for people
---
skill_id: smart-stories/hold-while-flagged
skill_version: 0.2.2
som_schema_version: ["1.0.0"]
skill_type: REFERENCE
category: compliance
lifecycle: draft
recall: # the advert
target_system_type: [mam, playout, rundown,
cms, compliance_hub]
conditions:
- kind: field
path: editorial_gates[].gate_type
op: equals
value: "{{ config.gate_type }}"
- kind: field
path: editorial_gates[].status
op: equals
value: PENDING
recall_on: ["story.context", …]
state_path: editorial_gates[].status
output_messages: ["skill.warning.raised"]
severity_range: [hold]
auto_change_content: false
fail_closed: true
migration_policy: GATED
disclosure_level: L2
depends: []
---
# hold-while-flagged
…what it is, config surface, runtime loop,
output contract, worked configurations,
eval set, open items, vendor build notesskill_id as publisher/name, a semver skill_version, the SOM schema versions it resolves against, a category and a lifecycle.
recall names which tool types may pick the skill up, the conditions over story paths (field and field_change), and which messages cause a look. Paths are literal and checked against the published schema; values can be templated from the house’s configuration.
One generic file with one house’s values loaded, watching one condition. A house runs several off the same file — a court restriction at story scope, an unconfirmed figure at link scope — and registers one advert row per configured instance.
hold / flag / inform, lower-case permanently. A skill declares which of them it can produce in severity_range.
| Guarantee | Value | What it means |
|---|---|---|
auto_change_content | false | The only permitted value. What is withheld is an action, never the content — an executor that edits to release has broken the model. |
fail_closed | true | An unreadable value is treated as the condition holding, at the loudest severity the skill has. Silence on an unreadable restriction is never allowed. |
output_messages | ["skill.warning.raised"] | A skill has one way to say anything. It never writes story state. |
depends | [] | Chaining happens over the bus, not through declared dependencies. A hold advertises against flag state, whoever raised the flag. |
som-skill-library 0.2.2
Ten reference skills, one proposed
All lifecycle: draft, origin: reference, resolving against SOM 1.0. Find your tool type in the lookup table, read the skills in that row, and configure them for your house.
| Skill | Declares | Category | Severity | Recalled by |
|---|---|---|---|---|
raise-flag-on-match | A named flag on a story when a configured field matches a configured value — at mint, even before any media exists. | compliance · X=1 | flaginform | planningrundownmamgraphicsdiscovery |
hold-while-flagged | A named action withheld while a flag of a configured type stands, released only by a clearance of equal or higher authority on the same scope. | compliance · X=1 | hold | mamplayoutrundowncmscompliance_hub |
gate-by-scope | Whether one destination path’s gate permits one telling right now. Always link-scoped. | compliance · X=1 | holdinform | cmsplayoutrundownmamdistribution |
record-provenance-on-ingest | That a source’s provenance is recorded as it enters a story — including an absent C2PA chain, recorded as absent. | compliance · X=1 | inform | mamingestverificationdiscoveryarchive |
flag-on-mismatch | A mismatch when a bound asset or rundown item carries a value the story no longer holds — naming both values. | editorial · X=2 | flaginform | rundowngraphicscmsplayout |
apply-clearance | Which member of a prepared version set a clearance makes current, and which members it supersedes. | workflow · X=3 | inform | playoutrundownmamcmsgraphics |
enrich-on-condition | That a named enrichment is warranted for an asset while a configured condition holds. It never runs the enrichment. | workflow · X=3 | inform | mamverificationmultimodaltranscriptioningest |
match-and-propose | A candidate story for a loose clip, at or above a house-set confidence. Confirmation is a human act recorded elsewhere. | workflow · X=3 | inform | multimodalmamdiscoveryingestrundown |
select-provider-by-context | Which provider the house’s policy resolves for a capability, given the story context. It never assigns or invokes. | workflow · X=3 | inform | transcriptionverification |
surface-on-context-match | An item from a monitored source that matches the running story, with its provenance. Additive, off the critical path. | workflow · X=3 | inform | transcriptionverificationdiscoverymarkets_datamamplanning |
declare-context-on-commitproposed | The story context that applies on a link when an asset is committed to a destination. | workflow · X=3 | inform | playoutmamgraphics |
When skills meet
Holds combine by conjunction
Where several gates bind the same fact on the same telling, it is served only when every one permits. “Most restrictive wins” and “story owner takes precedence” were formally withdrawn on 29 July 2026.
Precedence between two skills that clash on the same action is a separate question, ordered by X (category: compliance 1, editorial 2, workflow 3), Y (origin — every library skill is 5) and Z, which only the publishing house sets.
A skill that both declared a state and withheld something would sit in two positions at once. So “flag and hold” is two skills: flag-on-mismatch declares the flag, and hold-while-flagged advertises against flag state — whoever raised it, a skill or a lawyer.
That is why depends is empty everywhere: declaring a dependency would invert it and create a cycle at the first version change.
Fail closed. An unreadable configuration or story value is treated as the condition holding, at the loudest severity the skill has, and detail names what couldn’t be read. If a rule can’t be evaluated, the output it guards stays held and a person decides.
What doesn’t clear a hold: time passing, the flag simply missing from a later snapshot, a clearance at a different scope, a lower authority, an executor restart, or clearing a different flag. Releasing a hold is never an instruction to release the asset.
Validation
The library checks itself
Five scripts ship with the library, and each asks a different question — including whether the documents agree with the files they describe.
cd som/skills
python3 scripts/validate_som_skill.py skills/<name>.md # one skill file is legal
python3 scripts/check_library.py skills/ # the library holds together
python3 scripts/check_paths.py skills/ # every path resolves against
# ../schema/story-context.schema.json
python3 scripts/build_lookup_table.py . --check # the table matches the adverts
python3 scripts/check_cover_claims.py . # the docs match the filesOne gap is named rather than hidden: check_paths.py resolves literal paths only. A {{ config.* }} value is unknowable until a house configures it, so catching a bad configured path is registration-time work for the house.
Honestly open
What the library doesn’t claim to settle
- How authority is compared. “Cleared by equal or higher authority on the same scope” is the library’s working position, with the ordering supplied by each house as
authority_scale. No group has ratified it. - Who turns a raised warning into gate state. A raise skill only publishes a warning; a hold skill reads
editorial_gates[]. What materialises one into the other is not yet defined. - Scheme-qualified tag matching. Skills match
tags[].valueregardless of scheme today; whether to matchnewsroom:sportrather thansportis open. - Demo configuration. The configured instances used in the IBC walkthrough name individual vendors and are not published in 1.0, pending each vendor’s sign-off.