Savvi Studio

Modules Program Tracker

This tracker is the repository-visible status artifact for the modules program. Use it with the session tracker and preflight gates to keep scope unambiguous.

Program Scope

Phases:

  • A: lifecycle risk matrix and contract tests
  • B: Teams plus Webhooks cohesion slice
  • C: module.aion compile feedback loop modernization
  • D: taxonomy and expansion blueprint
  • E: token artifact bridge design
  • F: documentation finalization

Status Dashboard

Phase Status Exit Gate
A IN_PROGRESS high-severity risks mapped to passing or explicit contract tests
B TODO no placeholder data path in target slice
C IN_PROGRESS build:mod discovers module.aion and aggregates diagnostics
D TODO approved dependency-ordered taxonomy
E TODO additive token artifact bridge design approved
F IN_PROGRESS docs complete and linked to source references

Current Deliverables Completed

  • modules/README.md expanded into an actionable authoring guide.
  • Lifecycle workflow tests expanded with additional granular assertions.
  • Strict module entrypoint policy migrated to module.aion across compile/runtime/webpack/test fixtures.
  • Input-vs-in-memory manifest schema split implemented in graph-module-model.
  • JSON schema generation now uses graphModuleManifestInputSchema and completes successfully.

Risk Matrix (Phase A)

Risk Severity Current Coverage Target
install unknown module behavior High Added integration assertion keep passing
apply plan hash mismatch behavior High Added integration assertion keep passing
force uninstall dependency override behavior High Added integration assertion keep passing
dependency-blocked uninstall behavior High Existing integration assertion keep passing
plan drift detection on apply High Existing integration assertion keep passing
rename/deprecate lifecycle semantics High Not implemented contract tests/doc spec
namespace collision policy modes High Partial unit validation integration contract specs
partial-failure recovery semantics High Partial add targeted specs

Phase A Evidence Classification

Risk Status Evidence Notes
install unknown module behavior PASS modules-lifecycle.workflow.test.ts :: rejects install requests for unknown modules Verified in lifecycle workflow integration suite (8/8 passing run).
apply plan hash mismatch behavior PASS modules-lifecycle.workflow.test.ts :: rejects upgrade apply when plan hash does not match Confirms plan-hash tamper rejection contract.
force uninstall dependency override behavior PASS modules-lifecycle.workflow.test.ts :: allows force uninstall when dependencies exist Confirms force: true override path is functional.
dependency-blocked uninstall behavior PASS modules-lifecycle.workflow.test.ts :: blocks hard uninstall when dependencies exist Confirms non-force uninstall is dependency-gated.
plan drift detection on apply PASS modules-lifecycle.workflow.test.ts :: rejects lifecycle apply when plan source state drifts Confirms drift invalidates previously planned lifecycle operations.
rename/deprecate lifecycle semantics EXPECTED_FAIL modules-lifecycle.workflow.test.ts :: expected-fail: models rename/deprecate lifecycle semantics in upgrade planning Contract now encoded as expected-failing integration coverage.
namespace collision policy modes EXPECTED_FAIL modules-lifecycle.workflow.test.ts :: expected-fail: enforces explicit namespace collision policy modes Contract now encoded as expected-failing integration coverage.
partial-failure recovery semantics EXPECTED_FAIL modules-lifecycle.workflow.test.ts :: expected-fail: supports partial-failure recovery semantics for batched installs Contract now encoded as expected-failing integration coverage; implementation pending.

Blocker Log

Date Blocker Impact Owner Next Action
2026-03-20 ProviderNotFoundError for Symbol(root.config.loader) in lifecycle integration bootstrap chain Phase A lifecycle workflow contracts could not reach runtime assertions; 9 tests failed during init Modules/Instance bootstrap RESOLVED: registered testConfigLoaderProvider in integration fixture core providers
2026-03-20 Builtin manifest validation errors after schema tightening (numeric predicate bigint coercion, strict-key rejection for author/license) Lifecycle suite blocked at builtin manifest registration Modules/Schema RESOLVED: predicate schema kept JSON-safe and manifest base schema allows author/license metadata
2026-03-20 9 module manifests currently invalid for compileModuleDirectory (empty placeholder manifests and event/export schema mismatch) Immediate Phase C completion was blocked until intentional placeholders could be separated from strict compile targets Modules/Authoring + Compile RESOLVED: added explicit quarantine list consumed by build:mod; strict non-quarantined failures still fail command
2026-03-20 studio graph-module runtime bootstrap still attempts direct .aion import through graph-module-stdlib in tsx execution path graph-module CLI translate/compile command validation in this shell remains blocked by unrelated stdlib bootstrap wiring Modules/CLI + stdlib bundling Keep standalone translator entrypoint as active path; track stdlib bootstrap decoupling as follow-up

Source-of-Truth References

  • docs/forge-home/mvp-q1-2026/README.md
  • docs/forge-home/mvp-q1-2026/reference/DESIGN-DECISIONS.md
  • docs/forge-home/mvp-q1-2026/reference/STORIES-LIST.md
  • docs/forge-home/mvp-q1-2026/reference/WEEKLY-BREAKDOWN.md

Evidence Log

2026-03-20

  • Updated integration-tests/modules-lifecycle.workflow.test.ts with additional granular checks and module.aion manifest paths.
  • Expanded modules/README.md with conventions, testing strategy, and MVP-goal anchoring.
  • Migrated module discovery/import defaults to module.aion in compile/runtime/webpack/fixtures and stdlib/studio module bundles.
  • Added tools/vitest/aion-compiled-bundle-plugin.ts and wired it through vitest.config.ts.
  • Split manifest schemas in graph-module-model into base/input/in-memory with input->in-memory transform validation.
  • Verified schema generation gate: pnpm -s build:schema => SCHEMA_OK.
  • Verified package type gate: pnpm -s tsc -p configs/tsconfig.src-packages.json --noEmit (no diagnostics emitted).
  • Fixed integration fixture provider chain by registering testConfigLoaderProvider in core providers.
  • Updated graph template predicate schema to keep predicate inputs JSON-safe (string or expression) without bigint coercion.
  • Allowed author/license metadata fields in strict graph-module manifest base schema.
  • Verified lifecycle contract gate passes end-to-end: pnpm -s vitest run integration-tests/modules-lifecycle.workflow.test.ts --project integration-tests-web => 8 passed.
  • Added expected-failing lifecycle contract tests for rename/deprecate semantics and namespace collision policy variants.
  • Verified lifecycle contract gate remains green with expected-fail coverage: pnpm -s vitest run integration-tests/modules-lifecycle.workflow.test.ts --project integration-tests-web => 10 passed.
  • Added expected-failing lifecycle contract test for partial-failure recovery semantics in batched install operations.
  • Verified lifecycle contract gate remains green after partial-failure contract addition: pnpm -s vitest run integration-tests/modules-lifecycle.workflow.test.ts --project integration-tests-web => 11 passed.
  • Hardened build:mod to run manifests in deterministic sorted order, emit aggregate summary, list failed manifests, and exit non-zero when failures exist.
  • Verified hardened build:mod behavior: Total manifests=28, Compiled=19, Failed=9, command exit code=1 with explicit failed-manifest list.
  • Added explicit build:mod quarantine policy file at docs/reference/modules/build-mod.quarantine.txt for intentional placeholder manifests.
  • Updated build:mod to load quarantine list, skip quarantined manifests, and report Total/Quarantined/Attempted/Compiled/Failed with deterministic ordering.
  • Verified updated build:mod behavior: Total=28, Quarantined=9, Attempted=19, Compiled=19, Failed=0.
  • Added workspace catalog entry for jsonld and registered packages/graph-module-jsonld-translator in pnpm workspace package list.
  • Started schema.org translation implementation with packages/graph-module-jsonld-translator scaffold: JSON-LD fetch helper via content-loader and core.sdo module skeleton emitter.
  • Added standalone translator entrypoint at packages/graph-module-jsonld-translator/main.ts to bypass current studio CLI bootstrap issues while schema.org ingestion work continues.
  • Implemented graph-module translate command wiring plus standalone translate:schemaorg script for direct generation workflows.
  • Verified standalone translation path: pnpm -s translate:schemaorg --no-expand --output test-data/schemaorg.seed.module.aion (Normalized nodes: 3219).
  • Verified package type gate remains clean after translator entrypoint addition: pnpm -s tsc -p configs/tsconfig.src-packages.json --noEmit.
  • Implemented schema.org term emission in translator v1: deterministic resource_type and resource object generation from JSON-LD class/property nodes with generation limits.
  • Verified no-expand generation with constrained output: pnpm -s translate:schemaorg --no-expand --max-resource-types 60 --max-resources 60 --output test-data/schemaorg.seed.module.aion => generated 60 resource_type + 60 resource objects.
  • Verified expand mode now works with installed jsonld package and compatible import handling: pnpm -s translate:schemaorg --expand --max-resource-types 60 --max-resources 60 --output test-data/schemaorg.seed.expanded.module.aion.
  • Verified generated seed module compiles directly via compileModuleDirectory (bypassing studio CLI bootstrap): compiled core-sdo@0.0.1 with 120 objects.
  • Added focused translator tests in packages/graph-module-jsonld-translator/tests/translator.test.ts covering determinism, manifest schema compatibility, and jsonld expansion path.
  • Verified translator tests pass and package type gate remains clean after test additions.
  • Extended translator relationship mapping to emit schema_subclass_of (classes) and schema_domain_includes/schema_range_includes (properties) from JSON-LD relation fields.
  • Extended translator tests to assert relationship extraction and deterministic ordering for emitted relation arrays.
  • Re-verified translator tests and package typecheck after relationship mapping enhancement.
  • Wrote foundational schema.org module manifests to modules/: core.sdo (300 class + 300 property objects), core.sdo.types (500 class objects), core.sdo.properties (500 property objects).
  • Verified build gate discovers and compiles all new SDO modules: build:mod summary now Total=31, Quarantined=9, Attempted=22, Compiled=22, Failed=0.
  • Re-verified package typecheck remains clean after writing modules to repository.
  • Integrated SDO vocabulary dependencies into platform/application topology by adding core-sdo-types and core-sdo-properties module imports to platform-core and savvi.studio domain modules (studio, products, sponsors, tasks, teams, users).
  • Verified build:mod remains fully green after topology integration (Total=31, Quarantined=9, Attempted=22, Compiled=22, Failed=0).
  • Re-verified package typecheck remains clean after SDO import wiring.
  • Implemented partitioned SDO module output mode: module objects now support list-form relative path entries to object-list files partitioned by schema_id prefix (e.g., bibo, fibo, schema).
  • Added compiler support for object-list object files (single inline object or list/map section) with deterministic flattening and circular-reference guard.
  • Regenerated core.sdo/core.sdo.types/core.sdo.properties using partition-by-schema-prefix mode; core.sdo now references ./objects/*.objects.aion partition files.
  • Implemented optional semantic-link emission in translator writer: emits statement objects for selected elevated relations (core.subclass_of, core.domain_includes, core.range_includes) while retaining source data fields.
  • Verified targeted tests for translator and compiler partition support, full build:mod gate, and package typecheck all pass after partition + semantic-link changes.
  • Added savvi.studio module (modules/savvi.studio/module.aion); build:mod gate updated to Total=32, Quarantined=9, Attempted=23, Compiled=23, Failed=0.

Design decisions implemented (architecture session)

  • Added templateVisibilitySchema (public/protected/private) and templatePermissionsSchema (shorthand predicate→permissionLevel map) to packages/graph-module-model/model/objects/template.ts.
  • Added visibility and permissions optional fields to templateModuleObjectSchema; imports predicatePolicyPermissionLevelSchema from predicate-policy.
  • Added matchMode: 'exact' | 'subtree' (default subtree) to predicatePolicyModuleObjectSchema in packages/graph-module-model/model/objects/predicate-policy.ts. Field requires a pending DB migration to add match_mode column and update graph.has_permission to use <@ operator when match_mode = 'subtree'.
  • Added deriveTemplatePermissionPolicies() helper and Phase 4 in resolveObjectsSection of packages/graph-module-compile/node/module-compiler.ts: projects permissions shorthand blocks on template objects into derived predicate_policy objects at compile time. Unqualified predicate refs resolved against module namespace; ltree label normalization strips hyphens (-_).
  • Documented two-phase boot sequence in packages/graph-tasks/index.ts: Phase 1 (namespace reservation) delegated to engine during core module install; Phase 2 calls installModules().
  • Fixed pre-existing type narrowing bug in packages/graph-module-jsonld-translator/translator.ts: as: 'module' widened to string in spread context — fixed with as const.
  • Verified: pnpm tsc --noEmit clean; build:mod Total=32, Quarantined=9, Attempted=23, Compiled=23, Failed=0.

Next Actions

  1. Add DB migration: match_mode TEXT NOT NULL DEFAULT 'subtree' column to graph.predicate_policy; update graph.has_permission to use <@ when match_mode = 'subtree' and = when exact.
  2. Add predicate definitions/contracts for elevated SDO link predicates (core.subclass_of, core.domain_includes, core.range_includes) to modules/core.rdf/.
  3. Add usage conventions/docs for SDO vocabulary consumption and relation elevation policy in modules/README.md.
  4. Implement engine-side visibility enforcement for protected/private templates at import resolution time.
  5. Resolve studio graph-module CLI bootstrap coupling to graph-module-stdlib .aion import path so translate/compile commands can be validated through normal CLI flow.

2026-03-20 (SDO alignment + codegen architecture + test infrastructure)

SDO semantic alignment across modules:

  • Added optional sameAs: string field to predicateModuleObjectSchema (packages/graph-module-model/model/objects/predicate.ts) — documents semantic equivalence to external ontology predicates (e.g. schema:memberOf) without affecting runtime behaviour.
  • Added optional sameAs: string field to predicatePolicyModuleObjectSchema — same purpose for policy-level predicate alignment.
  • Extended core.type template (modules/src/core/templates/type.aion) with optional supertype input parameter stored in resource data; enables SDO-aware tooling to introspect type hierarchies.
  • Updated L1 platform modules with SDO supertypes and sameAs annotations:
    • core.identity: user→schema:Person, organization/provider→schema:Organization, role→schema:OrganizationRole, session→schema:UserInteraction
    • core.permissions: member_of/owns predicates annotated with sameAs: schema:memberOf/schema:owns
    • core.collections: list→schema:ItemList, list-element→schema:ListItem, collection predicates aligned to schema:itemListElement, schema:member, etc.
  • Updated L2 business modules:
    • savvi.studio.sponsors: organization→schema:Organization; sponsors-of predicate sameAs: schema:sponsor
    • savvi.studio.teams: team→schema:Organization; membership predicate sameAs: schema:member
    • savvi.studio.users: profile→schema:Person
    • savvi.studio.products: item→schema:InsurancePlan (broad enough for health, accident, critical illness, life, disability)
    • savvi.studio.tasks: item→schema:Action; predicates aligned to schema:agent/schema:object; task types (upload/review/approval/config/delegation) mapped to Action subtypes in comments
    • savvi.studio.plan-years: rewritten from events-only to proper domain module; plan-year→schema:Event with has-plan-year (schema:subEvent) and offers (schema:offers) predicates
    • savvi.studio.environments: new module — environment→schema:SoftwareApplication, plan-mapping→schema:Thing
  • Verified build:mod and package typecheck remain clean after all module changes.

Codegen architecture improvements:

  • Added packages/codegen-model/abstract-model.ts: language-agnostic intermediate representation (AbstractModel, AbstractType, AbstractField, AbstractFunction) decoupling Postgres introspection from TypeScript AST generation. Enables future alternative output targets (JSON Schema, OpenAPI, Markdown) from the same model.
  • Added packages/codegen-model/store.ts: CodegenObjectStore interface + GeneratedFile type — decouples code generation from filesystem I/O (mirrors graph-module-compile artifact pipeline pattern).
  • Added packages/codegen-engine/stores/fs-store.ts: FsObjectStore implementation with atomic directory swap (fs.rename on same device; backup-then-replace fallback for cross-device). Generated files are never visible in a partially-written state.
  • Added packages/codegen-engine/stores/memory-store.ts: MemoryObjectStore for dry-run mode and unit tests.
  • Added packages/codegen-engine/builders/ast/deferred.ts: DeferredRegistry + createDeferredRef(key: symbol) using a module-level WeakMap<ts.Node, symbol> to tag placeholder AST nodes. Resolves forward references (import paths, cross-file type refs) after all generation is complete via ts.transform() visitor pass.
  • Updated packages/codegen-engine/type-checker.ts to use ts.findConfigFile() starting from the destination directory, falling back to workspace root tsconfig. Now honours all project compiler options (paths, moduleResolution, strict, etc.) instead of a hardcoded config path.
  • Exported all new types from packages/codegen-model/index.ts, packages/codegen-engine/stores/index.ts, and packages/codegen-engine/builders/ast/index.ts.

Migration separation (DB architecture):

  • Removed migrationRunner dependency from the non-ephemeral path of createPostgresAppDatabase (packages/db-postgres/provision.ts). Regular (production) DB creation just creates the pool; no migrations.
  • Removed migrationRunner dependency from createPGliteAppDatabase (packages/db-pglite/provision.ts). PGlite creation just wraps the PGlite instance; no migrations.
  • Preserved ephemeral path: createPostgresAppDatabase(config, authenticator, migrationRunner?) still creates + migrates a fresh temporary DB when config.database.ephemeral = true and a migration runner is provided. Integration tests continue to get isolated pre-migrated databases.
  • Updated defaultStudioInitTask (packages/instance-boot/tasks.ts) to explicitly run migrations (Step 1) before calling graphInitTask (Step 2). The lifecycle task now owns the migration concern for non-ephemeral deployments.
  • Updated appDatabaseProvider (packages/providers-node/db.ts) to pass migrationRunner to createPostgresAppDatabase — used only for the ephemeral path; ignored in production mode.

Dev environment and test infrastructure fixes:

  • Updated .env.development with STUDIO_DATABASE_PORT=54320 and PGPORT=54320 to point local dev to the Docker postgres port mapping (54320:5432). Added STUDIO_DATABASE_TYPE=postgres and PGHOST=localhost as explicit defaults.
  • Updated integration-tests/fixtures/codegen-fixtures.ts to extend studioInstanceTestBuilder() instead of creating a raw Postgres pool. The newDbClient fixture now uses adminClient from the fully-migrated Studio instance, fixing the codegen-db-contract test that was failing with empty schema list.
  • Verified: pnpm test:unit — 98 files passed, 0 failed. pnpm test:integration:node — 27 files passed, 0 failed (was 1 failure on codegen-db-contract).