project.registry.schema.example.json
{
"system": {
"extensions": ["tools", "scripts", "docs", "php", "audit", "tests"]
},
"apps": [
{
"appname": "defapp",
"path": "websites/apps/defapp",
"role": "pilot-reference-template",
"extensions": []
},
{
"appname": "register",
"path": "websites/apps/register",
"extensions": []
},
{
"appname": "aiwizard",
"path": "websites/apps/aiwizard",
"extensions": []
},
{
"appname": "family-tree",
"path": "websites/apps/family-tree",
"extensions": ["api", "assets"]
},
{
"appname": "stockquotes",
"path": "websites/apps/stockquotes",
"extensions": ["python"],
"notes": "venv/ under python/ must be gitignored, never committed"
},
{
"appname": "theme-manager",
"path": "websites/system/tools/theme-manager",
"role": "moved-from-app-to-system-tier"
},
{
"appname": "aicode",
"path": "websites/system/php/aicode",
"role": "moved-from-app-to-system-tier"
}
],
"_schema_notes": {
"extensions": "Array of declared extension-zone folder names beyond the mandatory skeleton. Audit tool skips these. A non-mandatory folder present on disk but undeclared is an audit failure; a declared name missing on disk is also a failure.",
"allowed_app_extensions": ["api", "python", "assets", "themes"],
"allowed_system_extensions": ["tools", "scripts", "docs", "php", "ai", "audit", "tests"],
"tiering_rule": "System-scope content (2+ apps, or the tooling system itself) -> system.extensions. App-specific content -> apps[].extensions.",
"mandatory_per_app_v2": "public, admin, pages, templates, config/templates, css/themes, js, img, php, data/{config,fonts,logs,sql}, docs/{adr,runbooks}, ai/{prompts,output}, audit, tests, scripts, tools, tmp, var/sessions",
"optional_per_app": "src/{Controllers,Helpers,Parser} for OOP-style apps only",
"sessions": "moved to system tier (shared/SSO scope), not app tier - system/data/tmp/sessions/",
"config_scope_rule": "storage decided by cardinality of who is affected, not who edits: system-wide -> system/data/config/, app-wide -> {appname}/data/config/, per-user -> user_preferences DB table (never filesystem), per-session -> system/data/tmp/sessions/",
"user_preferences_table": "system/data/sql/user_preferences.sql - key-value rows keyed on (user_id, appname nullable, pref_key), extends existing users/groups/user_groups/login_logs schema",
"manifest": "middle ground - appname.manifest file is authoritative per app; project.registry.json is auto-generated from all manifests, not hand-edited"
}
}