Skip to content

[finding] sys_activity declares environment_id as a live, indexed, non-deprecated column while its sys_metadata twin is marked deprecated — and no writer in this repo sets it #13433

Description

@claude

Surfaced by the persistence-layer census that #13368 / PR #13431 required (root AGENTS.md line 8's DB-column item). ⛔ Filed unassigned — recording only, not claimed. ⛔ No domain:* set — triage's field.

The reading

sys_activity declares environment_id as an ordinary, non-deprecated field and puts an index on it:

packages/plugins/plugin-audit/src/objects/sys-activity.object.ts:264
    environment_id: Field.lookup('sys_environment', {
      label: 'Environment',
      readonly: true,
      searchable: true,
      description: 'Environment context (multi-environment deployments)',
      group: 'Context',
    }),

packages/plugins/plugin-audit/src/objects/sys-activity.object.ts:287
    { fields: ['environment_id'] },

No writer in this repository sets it. The audit plugin's own row builder is packages/plugins/plugin-audit/src/audit-writers.ts — it constructs the row and calls sys.object('sys_activity').create(activityRow) at line 725, and it conditionally sets organization_id at line 1367 (if (objectHasField('sys_activity', 'organization_id'))). It never sets environment_id. A repo-wide grep of packages/plugins/plugin-audit/src for the column finds exactly the two lines quoted above — the declaration and its index — and finds zero occurrences of the camelCase environmentId.

⚠️ What is NOT claimed

  • Not claimed that nothing anywhere writes it. sys_activity is reachable from an app's own server-side action (ctx.api.object('sys_activity').insert(...)), and the object's own header comment records measured writer sites living in objectstack-ai/hotcrm. This grep covers this repository only. Establishing the real answer needs the sibling repos read too — which is exactly why this is filed rather than acted on.
  • ⛔ Not claimed the field should be removed. If a cross-repo writer exists, the honest fix may be the opposite: nothing to do at all.

Why it is worth a card

The asymmetry, not the column. The sibling environment_id on sys_metadata is marked deprecated in both the declaration and the spec —

packages/metadata-core/src/objects/sys-metadata.object.ts:144  label: 'Environment (deprecated)'
packages/spec/src/system/metadata-persistence.zod.ts:115       'Deprecated (ADR-0006 v4) … New code must use organization_id only.'

— while this one carries a plain label: 'Environment' and an index, so an author reading the two objects side by side gets opposite signals about the same column name. If it has no writer it is an inert declaration paying an index's cost; if it has one, it is a live surface whose deprecated-looking twin needs disambiguating. Either way the two declarations should not read as contradicting each other. ⭐ This lands on the "make AI-written metadata hard to get wrong" axis: a declared, indexed, non-deprecated column is exactly what a generator copies.

Re-check

git grep -n "environment_id\|environmentId" -- packages/plugins/plugin-audit/src
git grep -n "organization_id" -- packages/plugins/plugin-audit/src/audit-writers.ts

⛔ Reverse-check any zero against organization_id in the same tree — it answers non-zero, so the grep is live.

Duplicate check

Full enumeration of all 360 open non-PR issues via the REST list endpoint (4 pages, page 5 empty — complete, not a truncated scan), grepped locally. Positive control in the same pass: 33 open cards contain "AGENTS.md", so the instrument is not returning false zeroes. Only neighbour mentioning sys_activity is #13416, a different subject (createFieldPresenceProbe's docstring about organization_id injection). ⛔ No open card covers this.


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions