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:

RealmRootDescribes
Filesystemfs:/Directories, whole files, and settings inside supported files.
Registrywinreg:/Windows Registry hives, keys, and values.
Windows Runtimewinrt:/Display, audio, device, and other Windows settings.
REST servicesrest:/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 nameAuthor 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:

ItemtypeChildrenPurpose
fs_rootdirectoryFilesystem realm root. Pinman usually creates it automatically.
winreg_rootwinreg_hiveRegistry realm root.
winrt_rootwinrt_section, winrt_tableWindows Runtime realm root.
rest_rootrest_serviceREST 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:

ConstructPurpose
itemtype: virtualGroups children that share inherited metadata, including children from different realms.
for: blockDefines 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:

ItemtypeFile formatChildren
ini_fileINIsections, tables, rows, properties
xml_fileXMLsections, tables, rows, properties
json_fileJSONsections, tables, rows, properties
yaml_fileYAMLsections, tables, rows, properties
csv_fileCSVrows and properties
sqlite_fileSQLitetables, 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 itemtypeChild selectorInferred child itemtype
directoryProfilesdirectory
directorysettings.ini, config.xml, data.json, config.yaml, or players.csvCorresponding file itemtype
directorylibrary.sqlite, library.sqlite3, or library.dbsqlite_file
directoryAnother filename, such as theme.datfile
ini_fileA name such as Displayini_section
ini_fileA path such as Display/Widthini_property
A section or rowA name such as WidthProperty 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:

FormatNatural structureItemtypes used below the file
ININamed sections contain properties. A dynamic family of sections can form a table.ini_section, ini_table, ini_row, ini_property
XMLElements can nest, and repeated elements can form a table.xml_section, xml_table, xml_row, xml_property
JSONObjects can nest, and a collection can form a table.json_section, json_table, json_row, json_property
YAMLMappings can nest, and a collection can form a table.yaml_section, yaml_table, yaml_row, yaml_property
CSVThe file is a table containing rows and properties.csv_row, csv_property
SQLiteThe 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}}/score when 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:

ParentSelector shapeMeaning
directoryconfig.iniNamed child file.
directorysubfolderNamed child directory.
ini_fileSectionNamed INI section.
ini_fileSection/KeyINI property with section backfill.
csv_file, sqlite_table{{KEY}}/PropertyProperty template for every primary-keyed row.
*_row or *_sectionPropertyProperty in that row or section.
winreg_hive, winreg_keyrelative pathKey path below the parent.
rest_servicegroup/propertyDeclared 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:

RealmContinue with
Files and structured settingsSupported file formats
Windows RegistryWindows Registry
Windows RuntimeWindows Runtime
REST servicesREST schema items

For metadata shared by properties in these realms, see Schema property fields.