Task: Remove explicit model properties the bound profile already fixes
Table of Contents
This page documents a task in the Entity classification and drift baseline: redundant explicit properties story. It captures the goal, current status, acceptance, and any notes or results.
1. Goal
Remove the explicit property lines from every profiled entity model where the bound profile already fixes the same value, so the profile is the single source of truth for those features. Keep genuine overrides and the structural properties profiles deliberately omit. Prove each removal output-neutral by regenerating the component.
2. Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | Entity classification and drift baseline: redundant explicit properties |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-09-17 |
3. Acceptance
- Every entity model bound to a profile is surveyed for explicit properties the profile also assigns, across every component in the drift gate's known-drift-free registry.
- Every redundant line is removed. Every line whose stated value differs from the profile's is kept and recorded with its reason.
- Each affected component regenerates byte-identical output after the removal. A component whose output moves is a finding, not a pass.
- The drift gate still passes for each affected component in
KNOWN_DRIFT_FREE.
4. Plan
The survey is mechanical, so it is a script, not a reading. It parses each
model's :profile:, loads that profile's * Assignments table through the
generator's own _load_profile_assignments, and intersects the assigned
feature names with the keys the model states explicitly. Reusing the
generator's loader matters: the survey then agrees with the merge the
generator actually performs.
Each intersection is one of two things. The stated value equals the profile's, which makes the line redundant. Or the stated value differs, which makes it a deliberate override that the profile's default must not replace. Only the first kind is removed; the second is recorded.
Removal alone proves nothing, because a profile supplies defaults and the generator merges them at a specific point in its pipeline. The proof is regeneration. The model edits are committed first, since the drift check diffs the whole tree and a modified model would show up as drift. With the tree otherwise clean, the check regenerates each affected component and requires the generated output to match byte for byte.
5. Notes
The survey is a script, not a reading. It parses each model's
:profile:, loads that profile's * Assignments through the
generator's own _load_profile_assignments, and intersects the assigned
feature names with the keys the model states. Reusing the generator's
loader matters: the survey then agrees with the merge the generator
actually performs.
The survey runs over projects/*/modeling/*.org for the components in
KNOWN_DRIFT_FREE. It found 47 intersections: 45 candidates to remove
and 2 overrides to keep.
| Feature | Lines | Outcome |
|---|---|---|
has_uuid_primary_key |
19 | removed |
has_pagination |
8 | removed |
has_tenant_id |
7 | removed |
has_change_reason_cache |
7 | removed |
has_parent_id |
4 | restored, not removable |
has_workspace_id |
1 | override, kept |
compute.result sets has_change_reason_cache false against the
profile's true. reporting.report_definition sets has_workspace_id
true against the profile's false. Both are deliberate overrides, so both
lines stay.
The four has_parent_id lines did not turn out to be removable. The
first regeneration proved it: removing them dropped the hierarchy
function, the repository method, the handler and the service for
business_unit, counterparty and party in refdata, and for folder
in synthetic, over 24 and 8 generated files. The cause is a namespace
mismatch. The profile files has_parent_id under sql, because that is
what _FEATURE_NAMESPACE says. The templates and core.py read it at
the entity root. The explicit line was the only thing putting the value
where the readers look. Those four lines are restored.
dq is out of scope. Its models carry the same redundancy, but neither
dq nor dq-cpp is in KNOWN_DRIFT_FREE, and regeneration there
already materializes 37 untracked files from a template family the
committed tree predates. The gate cannot prove a removal in an
unregistered component, so the sweep leaves it alone.
6. Test Scenarios
Manual QA scenarios (scaffolded via compass add test_scenario, run
through the QA Validation Runner panel) that verify this task. Link
new ones here as they're created; the scenario doc itself links back
via its "Verifies task" field.
| Scenario | State | Notes |
|---|---|---|
7. PRs
| PR | Title |
|---|---|
| #2089 | [codegen] Remove model properties the bound profile already fixes |
8. Review
| Comment summary | File | Decision | Notes |
|---|---|---|---|
9. Result
The sweep removed 41 redundant property lines across 19 models in six
components. Every removal is proven output-neutral by regeneration: all
seven registry catalogue entries report No drift on the committed tree.
| Catalogue slug | Result |
|---|---|
analytics-cpp |
No drift |
compute-cpp |
No drift |
iam |
No drift |
iam-cpp |
No drift |
refdata |
No drift |
reporting |
No drift |
synthetic |
No drift |
Two findings came out of the run.
The four has_parent_id lines are not removable. Regeneration dropped
the hierarchy machinery for the three refdata hierarchy entities and for
synthetic.folder, because the profile writes the feature into the sql
namespace while the generator reads it at the entity root. The lines are
restored and the removal waits for a generator fix.
dq is out of scope. Its models carry the same redundancy, but neither
dq nor dq-cpp is in KNOWN_DRIFT_FREE, and regeneration there
already drifts for an unrelated template reason.
The audit gained the check. Model and profile hygiene joins the manual
checklist of the component architecture audit, so a later pass on
any component looks for this class of finding.
Acceptance:
- Survey across the registry: met. The survey covers every profiled model of the six registry components.
- Redundant lines removed, overrides kept and recorded: met. 41 lines
removed. The two overrides and the four restored
has_parent_idlines are recorded in* Noteswith their reasons. - Each affected component regenerates byte-identical: met, for all seven registry entries.
- The drift gate still passes for each affected component in
KNOWN_DRIFT_FREE: met, by the same seven runs.