# `StatifierBlocks.Core.Placeholder`
[🔗](https://github.com/riddler/statifier_blocks/blob/v0.44.1/lib/statifier_blocks/core/placeholder.ex#L1)

`core.placeholder`: an in-flow leaf marking a gap the author has left on
purpose (ADR-0002's amendment of 2026-08-31, section G10).

It compiles to a step that does nothing and it warns. Both halves matter.
The step is real, so the chart runs and a preview walks straight through
the gap - an author previewing a half-built workflow sees the half they
built, which is what makes a marker cheaper to place than a hole. The
warning is where the reminder belongs: in the compile, addressed to the
author, rather than in the running machine addressed to nobody
(ADR-0004's amendment of the same date, D4 and D5).

## Declarations

Every callback but four is the default `use StatifierBlocks.BlockType`
injects (ADR-0007 decision 1), and that is the point rather than an
economy. `io/1` in particular takes ADR-0003 decision 5's permissive
default in full - `kinds: [:step]`, `consumes: :unknown`,
`produces: :unknown` - which section A3 of that record's amendment states
is the honest answer: a gap goes wherever a step goes, and declaring
anything narrower would be this package deciding what an author's
unwritten step was going to do.

The one config field, `note`, is prose and this package never reads it.
It exists so a gap can carry the author's own words into the editor's
card and into the compile warning. Nothing parses it, nothing routes on
it, and an empty one is not a finding: an unexplained gap is still a gap,
and refusing one would make the marker more expensive to place than
leaving the hole unmarked, which inverts the whole point (G10b).

No `icon` is declared. The icon seam treats an entry that names no icon
as a nameless entry rather than a missing one and draws no tile at all,
and a marker for something not yet written is exactly that case.

## Against `core.drafts`

The two types are opposites and shipped together on purpose (G10a).
`StatifierBlocks.Core.Drafts` holds work that is **not** in the flow and
says nothing about it; a placeholder block **is** in the flow and says
something is missing from it. An author moving a fragment off the shelf
into the flow is filling a gap; an author who has not built the fragment
yet marks the gap instead.

## The word "placeholder"

The compiler already uses it: an `StatifierBlocks.Emission` carries
`{:child, block_id}` markers that ADR-0004 decision 10's Emit stage
splices each child's emission into, and both the code and that record
call those **child placeholders**. They are an internal step of one
compile, never stored, never rendered and never seen by an author. A
placeholder block is the opposite in every one of those respects
(G10a-i).

# `emit`

The smallest thing a step can be: one compound state carrying a single
`<final>` reached on entry, so the block completes immediately and the
parent's ordinary `done.state` sequencing carries on to the next sibling
(D5).

    <state id="s_blk_PLA" initial="s_blk_PLA__done">
      <final id="s_blk_PLA__done"/>
    </state>

There is no `<log>`, no raised event and no data written. A marker that
announced itself into the chart would be a marker the author had to
remember to remove before the chart was real.

# `validate_config`

Refuses a `note` that is not a string, and refuses nothing else. An
absent `note` and an empty one are both accepted (G10b).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
