Seed attribute ownership audit (AB#6317)
A blueprint update imports its seed with Upsert, which is a full replace of the entity. Which attribute values survive
depends on the effective ownership of every attribute (see Blueprints
and the engine rules Attribute Ownership): SeedOwned (default) is overwritten by the seed, TenantOwned,
RuntimeState and Secret keep the stored value. Since AB#6313 the engine additionally keeps a non-empty stored value
when a SeedOwned attribute arrives empty or omitted (the seed value guard); a non-empty, different seed value still
wins. This audit lists, for every platform and app blueprint, which attributes the seeds write, who owns them, and which
of them hold values that a tenant enters or changes. It is generated and can be rerun at any time.
Result
- Scope: 26 blueprints with 138 seed files and 2951 seed entities, resolved against 32 CK models (origin/main snapshot of 2026-10-10, repositories below).
- Seed-written attribute rows: 899 (one row per blueprint, CK type and attribute):
SeedOwned674,RuntimeState158,TenantOwned60,Secret7. No attribute was left unresolved. - Name-heuristic triage of the written rows: blueprint 607, runtime 154, tenant (already marked) 60,
tenant-looking but
SeedOwned37, credential-looking 41 (of these 22 areSeedOwned). EverySeedOwnedrow that looks tenant-entered or credential-like was reviewed by hand and is reconciled below; one is a new finding (N1). - Omitted attributes: 324
SeedOwnedattributes of seeded types are not written by the seed (table 2 of the full table); the guard keeps their non-empty stored value, except attributes with a CK default (AB#6395).
Reconciliation with the findings and decisions
| Id | Where | Ownership today | Work item | State |
|---|---|---|---|---|
| F1 | System.Communication/Adapter.AdapterConfiguration | Secret | AB#6312 | fixed (System.Communication 4.7.0) |
| F2 | System.Identity/DataPolicy PolicyEnforcementMode, PolicyScope | TenantOwned | AB#6324 | fixed (System.Identity 2.23.0) |
| F3 | Meshmakers.Accounting/CategorizationRule rule attributes, CostCategory, FiscalYear | SeedOwned | AB#6325 | open |
| F4 | System.StreamData archives Archive.RawRetentionMs, Archive.MaxRetroactiveReachMs | SeedOwned, omitted by all seeds | AB#6328 | open |
| F5 | System.Identity Client/ApiResource/ApiScope/IdentityResource Enabled, AllowedScopes, AllowedGrantTypes, AutoProvisionInChildTenants, Client Secrets | TenantOwned / Secret | AB#6329 | fixed (2.23.0), except N1 |
| F6 | System.Communication PipelineTrigger.CronExpression, Pipeline.PipelineDefinition | SeedOwned | AB#6328 | open |
| F7 | System.Ai AiQuotaLimit, AiAgentConfig, AiToolPolicy | SeedOwned | AB#6328 | open |
| F8 | System.Communication/EnergyCommunityConfiguration | RuntimeState (kept, lost on ExportRt) | AB#6328 | open |
| F9 | System.UI Dashboard, DashboardWidget | SeedOwned | AB#6328 | open, policy decision first |
| F10 | FamilyOs Household, CalendarCategory | not in scan scope | AB#6328 | open |
| N1 | System.Identity/ApiResource.Secrets (the seed writes it empty, api-resources.yaml:42) | SeedOwned | AB#6443 | new, found by this re-scan |
| D1 | System.Communication/AiConfiguration AiModel, MaxTokens, Temperature | SeedOwned on purpose | comment in the CK attribute file | decision: a model bump must reach every tenant |
| D2/D3 | ServiceAccountConfiguration.IssuerUri, System/TenantId | SeedOwned on purpose | AB#5027, AB#5115 | decision: empty means "own installation" |
| D4 | other System.Identity/Client flags (token lifetimes, RequirePkce, ...) | SeedOwned | AB#6329 comment | decision: stay blueprint-owned |
| R1-R8 | policy coverage, Helm repository URLs, rollup time zone, saved query limits, sample data, form flags | SeedOwned | - | reviewed, blueprint-owned (reasons in the table) |
Open question (no evidence of a tenant edit yet): saved queries (System/*Query) shipped by the app blueprints are
SeedOwned; if tenants edit them in Studio, the same decision as for F9 applies.
Blueprints in scope
| Blueprint | Seed files | Seed entities | Written attribute rows | of which SeedOwned |
|---|---|---|---|---|
| EnergyCommunity.App-2.1.0 | 1 | 2 | 54 | 37 |
| EnergyCommunity.Base-2.11.1 | 14 | 48 | 87 | 66 |
| EnergyCommunity.Billing-2.8.1 | 18 | 63 | 52 | 44 |
| EnergyCommunity.EdaIntegration-2.11.0 | 12 | 49 | 60 | 40 |
| EnergyCommunity.Simulation-2.8.2 | 4 | 11 | 8 | 5 |
| MeshmakersAccounting.Host-2.0.0 | 1 | 2 | 30 | 15 |
| MeshmakersAccounting.Tesla-2.2.0 | 2 | 4 | 17 | 6 |
| MeshmakersAccounting-2.3.1 | 33 | 159 | 119 | 72 |
| System.Ai.Default-2.0.4 | 1 | 7 | 18 | 18 |
| System.Notification.Bootstrap-1.0.0 | 1 | 4 | 5 | 1 |
| System.Communication.MainLatest-2.1.0 | 1 | 4 | 21 | 10 |
| System.Communication.Release-2.1.0 | 1 | 4 | 21 | 10 |
| Locations.Austria-1.2.0 | 11 | 2364 | 7 | 7 |
| Samples.EnergyEnvironment-1.1.0 | 7 | 89 | 107 | 107 |
| Samples.Maintenance-1.1.0 | 1 | 6 | 5 | 5 |
| Samples.Photovoltaics-2.0.1 | 3 | 17 | 26 | 21 |
| Samples.PipelineBasics-2.0.0 | 2 | 6 | 10 | 8 |
| Samples.Simulator.EnergyCommunity-2.0.0 | 3 | 16 | 13 | 11 |
| System.Identity.Bootstrap-1.3.1 | 11 | 33 | 58 | 44 |
| Office.ExcelImport-2.0.0 | 1 | 2 | 6 | 5 |
| System.TenantMode-1.1.0 | 1 | 1 | 4 | 1 |
| System.UI.EntityForms-1.5.0 | 1 | 25 | 18 | 18 |
| System.UI.SystemCockpit-1.1.0 | 1 | 13 | 15 | 15 |
| System.UI.TenantCockpit-1.3.0 | 1 | 7 | 15 | 15 |
| SmartMeterInsights.Base-2.0.0 | 5 | 14 | 82 | 60 |
| SmartMeterInsights.Dev-1.0.0 | 1 | 1 | 41 | 33 |
Method
- Every
blueprint.yamlbelow the repositories is read; itsseedDataPath/seedDataPathsfiles are parsed, entity by entity and attribute by attribute (file and line are kept as evidence). - The CK models (
ConstructionKit/ckModel.yamlwithattributes/,types/,records/) are loaded. An attribute of value typeSecretis alwaysSecret. For all others the effective ownership of an attribute on a type is the nearest assignment override on the type chain (ownership, else the deprecatedisRuntimeState), otherwise the attribute definition, otherwiseSeedOwned. Element-version suffixes (-1) are ignored. - Each row is triaged by attribute name (credential, runtime, tenant-looking, blueprint) as an aid, not as a verdict. Every
SeedOwnedrow that looks tenant-entered or credential-like is judged by hand against the CK description and the seed and recorded infindings.yamlas a finding (work item) or a decision/review (reason). - A seed file that a manifest references but that is missing aborts the run (no silent gaps).
- Table 2 lists
SeedOwnedattributes of seeded types that no seed entity of the type writes (engine-stampedSystem/Rt*attributes are left out).
Scope and limits
- Repositories (origin/main snapshot, 2026-10-10): energy-community c0cb64a, meshmakers-app 65aa8c2, octo-ai-services fd4c85c, octo-common-services 1556366, octo-communication-controller-services bf45f46, octo-construction-kit ca257e7, octo-construction-kit-engine 9d5ce4d2, octo-identity-services 426fe8d, octo-office-integration 3f2c142, octo-platform-services 7ea5157, smart-meter-insights 5d7049e, plus the CK-only repositories octo-bot-services c3eb571, octo-report-services d312522, octo-communication-sdk 2142169, octo-adapter-loxone feeee40 and the demo/landing repositories landing-pages f0cbc7c, wwc26-landing-page c382c2f, demo-energy-iq cd0477c and demo-process-automation d867932 (19 repositories in total; the last four contribute CK models only, no blueprint).
- Not covered because they are not in the scanned repositories: the FamilyOs and one-time-ticket blueprints and the
private FdaSeen catalog. Blueprint samples under
samples/, test fixtures and drafts are skipped. - The audit reads source files only. It does not know which tenants run which blueprint version and does not judge values on a tenant; whether a value is actually edited by tenants comes from the CK description, the seed comments and the work items.
- Attribute-level ownership only. A pipeline definition or a dashboard layout is one attribute value (F6, F9).
Regenerate
The script and findings.yaml are in scripts/seed-ownership-audit/ of the octo-documentation repository; its README.md
has the snapshot loop and the command. The full tables are on the page
Seed ownership audit: full table.