Starting the Schemas

So, discovery is working. Now we need to define what we are discovering.

This is where the schemas come in.

The goal is to have a strict contract for every part of the system. If Velnora detects a package, it needs to know exactly what that package is capable of.

The first question was: what does a discovered project actually look like at runtime? I needed a Project interface — a strict contract that captures everything the system needs to know about a package.

But package.json alone isn't enough. It gives you the name, version, and dependencies — but nothing Velnora-specific. Where does the adapter config go? The framework hints? The build targets? Polluting package.json with custom fields felt wrong.

So the Project interface pulls from two sources of truth:

On top of that, each project gets:

Two Levels of Configuration

The configuration itself works at two distinct levels:

  1. VelnoraConfig (Global): Lives in the workspace root. Defines the rules for the entire repo — plugins, shared defaults, and global overrides.
  2. VelnoraAppConfig (App-Specific): Lives inside each project folder. Defines the specific framework, build targets, and unique needs of that application. This is what ends up in Project.config.

By separating them, we get strict typing for each context while keeping the overall system cohesive.

The Pivot to Execution

But as satisfying as it was to define these interfaces, I realized something.