vitruvio source pull acquires from it and registers what
is new into canonical memory. Interpretation is unchanged and still separate — vitruvio task and
vitruvio ingest run are where a model gets to say what the evidence means.
[brain.sources.<name>]; a named project declares them under [brains.<brain>.sources.<name>]. The same source
kind and name may appear under several brains with different paths and options, and selecting a brain selects only
its declarations. Project-level [sources.<name>] declarations are invalid.
To migrate an older declaration, move the whole source table under its destination brain and delete the old
brain field:
Defaults in the declaration, overrides on one pull
options is the open, kind-specific part of a source. The declaration provides defaults, and a named pull may
override them for that invocation without rewriting vitruvio.toml:
self.options; command-line values win. Its constructor validates the
result exactly as it validates declared options. Values are parsed as booleans, integers or strings by the same rules
as source add.
Persistent differences belong in each brain’s declaration. --option remains useful for a one-off override and
never rewrites that declaration. It cannot be combined with --all, because one override set has no unambiguous
meaning across different source kinds in the selected brain.
Overrides are acquisition parameters, not hidden state. A plugin must include every value that changes a remote
item’s identity in that item’s stable origin — for example both course_id and resource_id. Otherwise two
courses that reuse an id could cause a false origin skip.
What stops the same thing being registered twice
Three layers, in the order they run:- The origin index. Before anything is fetched, one hash-map lookup answers “have I acquired this?”. This is the cheap layer: pulling a folder of a hundred unchanged files does a hundred lookups and no reads.
- The redaction guard. After the fetch, before the register. See below.
- Content addressing. Identical bytes compute the same block identity, so
registerreports a duplicate. The backstop for a source that cannot produce a stable origin: one wasted download, never a wrong result.
.vitruvio/, regenerated by
vitruvio index build like every other index — which is why there is no cursor file.
Changing a source’s media_type or normalize_with re-registers rather than being skipped. Both are part of a
canonical block’s identity, so a silent skip would make the correction do nothing and leave the wrong block in place.
Likewise, an item listed without a type does not trust an existing application/octet-stream registration: it is
fetched once so a FetchResult can replace that generic type. Once the origin holds a specific MIME type, later
pulls skip it before downloading again.
A pull can never restore redacted bytes
vitruvio retain redact destroys bytes under policy — for personal data, credentials, licensed material. A source
that still lists the same item would re-fetch exactly those bytes, and a scheduled pull would undo every redaction on
a schedule.
So a digest that was tombstoned is refused, out loud, and --refetch does not override it:
vitruvio source register.
Several brains
Select a brain before inspecting, adding, removing, or pulling its sources.--all means every source belonging to
that selected brain; it never crosses into another brain:
--all keeps going past a failure and exits 11 if any source failed. Being told which one of six went wrong is
better than stopping at the first and leaving four that would have worked unpulled and unmentioned.
This containment removes the old conflict between a project-level source’s brain field and the selected
--brain: there is no destination field to disagree with the source’s location. A multi-brain project with no
selected brain refuses every source command before it can acquire or register anything.
Where a pull can go wrong
status reports an unusable source as a row rather than failing, because one broken declaration must not hide the
five that are fine.
One risk worth stating plainly: a directory source composes with vitruvio dist push into a way to publish
something you did not mean to. Point one at the wrong folder and a private key becomes a canonical block,
content-addressed and Merkle-committed in a public repository — which cannot be cleanly retracted. source add
warns when a path sits outside the project directory. Read that warning.
Exit codes
Sources are plugins. What the configuration may name, and how to write a kind of your own, is on Writing a source kind.