✔ config directory and file path follow MOSAIC_CONFIG (1.867049ms)
✔ the fixture business validates and comes back frozen (6.613216ms)
✔ two instances may share a definition (1.553281ms)
✔ top-level refusals (4.394638ms)
✔ arbiters and projects (6.806464ms)
✔ role instances (4.007157ms)
✔ Vikunja bots (10.644466ms)
✔ a role without Vikunja takes no tracker block (3.567703ms)
✔ credential references match the definition's services (4.264474ms)
✔ launch (12.958131ms)
✔ loadBusiness: file checks (2.079948ms)
✔ loadBusiness: not a regular file (45.475837ms)
✔ loading writes nothing (1.248191ms)
✔ names that are Object.prototype properties don't count as declared (2.636431ms)
✔ the shipped example refuses as written and validates once filled in (0.938997ms)
✔ usage errors exit 4 (306.920279ms)
✔ validate: a good business exits 0 and prints instance digests (75.941648ms)
✔ validate: project files (372.761359ms)
✔ validate: missing files and a broken system config (286.961712ms)
✔ validate: credential reference problems exit 2 and name each one (92.078302ms)
✔ validate: a token file inside the repository is refused (69.525005ms)
✔ validate: role definitions come from MOSAIC_ROLES_DIR (212.064917ms)
✔ resolve: prints one instance's record (225.62473ms)
✔ resolve: refusals (438.939536ms)
✔ parse: exactly one of file or env, plus the service's date (2.990356ms)
✔ check: a good file has no problems (0.88057ms)
✔ check never opens the file: a write-only token passes (0.344506ms)
✔ check: file problems (1.133557ms)
✔ check: token files can't live in the repository or dataRoot, even through a linked directory (1.180256ms)
✔ check: dates and environment references (0.53199ms)
✔ path and load (2.600044ms)
✔ refusals (1.590197ms)
✔ systemVars flattens the validated config (2.334227ms)
✔ precedence: system, business, project, project role, agent (5.382138ms)
✔ limits narrow the definition and never widen it (2.738644ms)
✔ role.launch stays within-role only for the instance the launch block names (5.289806ms)
✔ limits.authority without role.launch leaves the launcher with no launch block (2.998882ms)
✔ limits.authority narrows cross-role actions too (1.66732ms)
✔ classify (1.855641ms)
✔ the record carries what the broker and launcher need (1.587725ms)
✔ digest: key order doesn't matter, any value change does (10.439567ms)
✔ refusals (3.815951ms)
✔ the four shipped version 2 roles load (3.112119ms)
✔ shipped role scopes match addendum B section 2 and the SR runbook (1.576915ms)
✔ shipped authority follows the note's table (0.5797ms)
✔ version 1 files keep loading with no authority (1.255039ms)
✔ the conductor policy isn't a role (0.287754ms)
✔ a missing role file is exit 4, a symbolic link too (0.465952ms)
✔ version 2 refusals (1.508511ms)
✔ authority: closed vocabulary, no gated-only action, no overlap (2.698625ms)
✔ credentials: Gitea scopes (0.935475ms)
✔ credentials: Vikunja scopes are a group-to-verbs map from the grantable list (1.273969ms)
✔ credentials: services (0.668012ms)
✔ contract: a non-empty regular Markdown file beside the role file (0.725598ms)
✔ every key names known layers and a merge rule (0.99936ms)
✔ unknown keys and wrong layers refuse (0.880079ms)
✔ types (2.195618ms)
✔ merge: defaults, then the most specific layer wins (0.322584ms)
✔ merge: limits only narrow, and provenance lists each source (0.431596ms)
✔ merge doesn't change its inputs (0.188001ms)
ℹ tests 60
ℹ suites 0
ℹ pass 60
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 2158.961409
