Authoring reference
Schema items
A Schema defines what Pinman tracks across files, Registry values, Windows
settings, and service properties. Each declaration under items: identifies a
Schema Item or describes how Pinman should create Items while scanning.
This page explains the shared Item model: locations, itemtypes, filesystem trees, dynamic children, and structured-file syntax. Continue to Schema property fields for value and UI metadata. The realm-specific references at the end cover the fields unique to files, the Registry, Windows Runtime, and REST services.
Locations#
A Pinman location identifies an Item and the realm where it belongs. The prefix names the realm:
| Realm | Root | Describes |
|---|---|---|
| Filesystem | fs:/ | Directories, whole files, and settings inside supported files. |
| Registry | winreg:/ | Windows Registry hives, keys, and values. |
| Windows Runtime | winrt:/ | Display, audio, device, and other Windows settings. |
| REST services | rest:/ | Declared properties and commands exposed by HTTP services. |
Filesystem locations#
Filesystem locations can be absolute, relative to a parent Item, or built from a binding:
- location: "fs:/C/ProgramData/Example" # absolute Pinman location
- location: "C:/ProgramData/Example" # becomes fs:/C/ProgramData/Example
- location: "Config" # relative to the parent
- location: "{{EXAMPLE_ROOT}}/Config" # resolved from a binding
The drive letter becomes the first path level beneath fs:/; its colon is not
part of the normalized Pinman location. Network paths use the server and share
beneath fs://, for example fs://server/share/Config.
Settings inside structured files#
For a setting inside a supported file, # separates the file location from the
path to the setting within that file:
fs:/C/Example/settings.ini#display/width
fs:/C/Example/config.json#Display/fullscreen
fs:/C/Example/data.csv#player-1/score
Schema YAML usually expresses these levels as relative strings through nested items:, so the full
location does not have to be repeated on every declaration.
Reserved characters in names#
selector and location contain location syntax. Encode a character when it is
part of an actual name rather than a separator.
| Character in the name | Author as |
|---|---|
% | %25 |
/ | %2F |
# | %23 |
? | %3F |
\ | %5C |
whole name . | %2E |
whole name .. | %2E%2E |
Spaces, colons, braces, brackets, and Unicode characters need no encoding. Smart export writes reserved characters encoded; Pinman displays the decoded name.
For example, these declarations represent a file named C# notes.ini and an
INI key named C:\Games\vpx:
- selector: "C%23 notes.ini"
itemtype: ini_file
items:
- selector: "Paths/C:%5CGames%5Cvpx"
Core itemtypes#
An Item's itemtype tells Pinman what the Item represents and how to locate,
read, compare, and—where supported—write it.
Each realm begins with its own root:
| Itemtype | Children | Purpose |
|---|---|---|
fs_root | directory | Filesystem realm root. Pinman usually creates it automatically. |
winreg_root | winreg_hive | Registry realm root. |
winrt_root | winrt_section, winrt_table | Windows Runtime realm root. |
rest_root | rest_service | REST service realm root. |
Pinman creates the schema root itemtype during import. Authored items: begin
below that root.
Two authoring constructs organize declarations without representing tracked machine state:
| Construct | Purpose |
|---|---|
itemtype: virtual | Groups children that share inherited metadata, including children from different realms. |
for: block | Defines a template for Items discovered during a scan. |
Filesystem Items#
Directories and whole files#
A directory represents a filesystem directory. A child with itemtype: file
represents one whole file; Pinman tracks its file-level state without
interpreting the contents.
This example declares a directory containing a whole-file asset:
items:
- location: "fs:/C/Example"
itemtype: directory
items:
- selector: theme.dat
itemtype: file
Pinman recognizes these general-purpose file formats and can expose settings inside them:
| Itemtype | File format | Children |
|---|---|---|
ini_file | INI | sections, tables, rows, properties |
xml_file | XML | sections, tables, rows, properties |
json_file | JSON | sections, tables, rows, properties |
yaml_file | YAML | sections, tables, rows, properties |
csv_file | CSV | rows and properties |
sqlite_file | SQLite | tables, rows, and properties |
This list may grow. See Supported file formats for the current list, format details, and additional application- or domain-specific formats.
Itemtype inference#
Pinman can infer many filesystem itemtypes from an Item's parent and selector. This keeps authored YAML compact and lets smart export omit fields that the surrounding structure already makes clear.
| Parent itemtype | Child selector | Inferred child itemtype |
|---|---|---|
directory | Profiles | directory |
directory | settings.ini, config.xml, data.json, config.yaml, or players.csv | Corresponding file itemtype |
directory | library.sqlite, library.sqlite3, or library.db | sqlite_file |
directory | Another filename, such as theme.dat | file |
ini_file | A name such as Display | ini_section |
ini_file | A path such as Display/Width | ini_property |
| A section or row | A name such as Width | Property itemtype for that file family |
If a file uses a familiar extension but its contents follow a different format, declare its itemtype explicitly rather than letting Pinman infer from the extension.
Relative paths and intermediate directories#
A selector or relative location can include several path levels. Here,
settings.ini is three levels below the declared parent:
- location: "fs:/C/Example"
itemtype: directory
items:
- selector: "Profiles/production/settings.ini"
itemtype: ini_file
Import adds the required intermediate directory Items. Smart export can collapse those levels back into the compact path. The complete location still distinguishes directories with the same name under different parents.
Explicit and implicit filesystem children#
An Item named under items: is explicit: its declaration identifies that exact
file or directory. A directory can also track children found on the filesystem
without declaring every name in advance.
Recursive descendant tracking#
track_descendants: true brings otherwise undeclared files and directories
into Tracked-only scans. The setting flows into subdirectories, making it useful
for a bounded tree whose complete contents matter. follow_links separately
controls whether a scan follows symlinks and junctions below the directory.
The include and exclude fields can then shape which implicit descendants Pinman tracks.
Inherited exclusions and exceptions#
exclude_match removes names selected by a pattern throughout the directory's
subtree. include_match overrides that rule for names you want to keep. Both
fields flow into subdirectories.
This example excludes temporary files and Cache directories, but keeps files
named keep.tmp. It also explicitly declares trackthis.tmp:
- location: "fs:/C/Example"
itemtype: directory
track_descendants: true
exclude_match: ["*.tmp", Cache]
include_match: [keep.tmp]
items:
- selector: trackthis.tmp
itemtype: file
Both keep.tmp and trackthis.tmp remain tracked. The include pattern protects
keep.tmp, while an explicit declaration always takes priority over an
exclusion.
Direct-child selection#
The _local fields apply only to direct children. Combining
exclude_local: ["*"] with include_local selects which direct children enter
the scan. Here, those children are settings.ini and Profiles:
- location: "fs:/C/Example"
itemtype: directory
track_descendants: true
exclude_local: ["*"]
include_local: [settings.ini, Profiles]
The local rule stops at that first level. The inherited
track_descendants: true allows Pinman to continue through the selected
Profiles directory.
for: blocks#
A for: block defines dynamic Schema Items. It pairs a binding name with a
pattern and supplies the Item template Pinman should instantiate for each
selected child.
This example creates a file Item for each .cfg file directly beneath
presets:
- selector: presets
itemtype: directory
items:
- for:
PRESET: "*.cfg"
items:
- selector: "{{PRESET}}"
itemtype: file
For a file such as dark.cfg, Pinman binds PRESET to dark.cfg and uses the
template to create the Item. The for: block itself adds no container to the
tracked tree.
To select directories instead, give the template the directory itemtype. This
example creates a directory Item for each child of machines, then tracks
settings.ini inside it:
- selector: machines
itemtype: directory
items:
- for:
MACHINE: "*"
items:
- selector: "{{MACHINE}}"
itemtype: directory
items:
- selector: settings.ini
itemtype: ini_file
An explicitly named child claims its name before Pinman considers for: blocks.
When several blocks accept the same name, the first block in YAML order supplies
the template. Schema format describes
wildcards, regular expressions, and ordering in detail.
Structured files#
A structured file is both a file and a container. Its file Item records the whole-file state; child Items expose addressable settings inside it. The file's data model determines which structural levels are available.
Sections, tables, rows, and properties#
The formats do not all have the same natural depth. Their Schema Items follow the structure each format provides:
| Format | Natural structure | Itemtypes used below the file |
|---|---|---|
| INI | Named sections contain properties. A dynamic family of sections can form a table. | ini_section, ini_table, ini_row, ini_property |
| XML | Elements can nest, and repeated elements can form a table. | xml_section, xml_table, xml_row, xml_property |
| JSON | Objects can nest, and a collection can form a table. | json_section, json_table, json_row, json_property |
| YAML | Mappings can nest, and a collection can form a table. | yaml_section, yaml_table, yaml_row, yaml_property |
| CSV | The file is a table containing rows and properties. | csv_row, csv_property |
| SQLite | The database contains tables, rows identified by primary keys, and properties. | sqlite_table, sqlite_row, sqlite_property |
Declare each structural level#
Each section, table, and row is an Item in the Schema tree. This complete CSV
example declares the player-1 row before its score property:
- selector: players.csv
itemtype: csv_file
primary_key: id
items:
- selector: player-1
itemtype: csv_row
items:
- selector: score
datatype: int
INI provides one compact exception: section/key directly beneath an
ini_file fills in the named section during import.
Primary-key property shorthand#
CSV and SQLite can expose one property for every primary-keyed row without
spelling out a complete row template. This declaration exposes score for
every CSV row identified by id:
- selector: players.csv
itemtype: csv_file
primary_key: id
items:
- selector: "{{id}}/score"
itemtype: csv_property
datatype: int
{{id}}/score is shorthand for a row placeholder with a score child. The
id value comes from the CSV primary key during a scan; it is not a const or
global binding. Import expands the shorthand into the same row-and-property
shape used by the rest of the Schema tree.
This shorthand and a for: block describe the same basic idea—a template
instantiated for data discovered during a scan—but they serve different levels
of control:
- use
{{id}}/scorewhen the primary key identifies every row and the same property applies to all of them; - use
for:when you need to name the binding explicitly, select a subset with a pattern, attach row metadata, or declare several children together.
Smart export may choose the shorter primary-key form when it can represent the same Schema without losing information.
File-format details#
The exact structure, identity fields, and read/write boundaries vary by format. Supported file formats lists the file itemtypes and summarizes each model. Its full format reference documents the supported operations and boundaries in detail.
Selector quick reference#
The selector is the Item's name or relative path beneath its parent. Its shape can also help Pinman infer the child itemtype:
| Parent | Selector shape | Meaning |
|---|---|---|
directory | config.ini | Named child file. |
directory | subfolder | Named child directory. |
ini_file | Section | Named INI section. |
ini_file | Section/Key | INI property with section backfill. |
csv_file, sqlite_table | {{KEY}}/Property | Property template for every primary-keyed row. |
*_row or *_section | Property | Property in that row or section. |
winreg_hive, winreg_key | relative path | Key path below the parent. |
rest_service | group/property | Declared service child path. |
When a selector's shape could mean more than one legal child type, declare
itemtype rather than relying on inference.
Realm-specific references#
Each realm has its own detailed reference:
| Realm | Continue with |
|---|---|
| Files and structured settings | Supported file formats |
| Windows Registry | Windows Registry |
| Windows Runtime | Windows Runtime |
| REST services | REST schema items |
For metadata shared by properties in these realms, see Schema property fields.

