Skip to content

withoutOperationPrivateKeys is now hand-copied into three packages — the __ convention has no single owner #7284

Description

@os-help

Observation from implementing #7204 (PR #7283), filed rather than fixed — that card's file surface is plugin-reports, and this spans three packages plus wherever the shared home would be.

Fact

The same ~10-line helper, with the same name and the same doc-block reasoning, now exists in three copies:

Each declares its own const OPERATION_PRIVATE_KEY_PREFIX = '__' and its own function withoutOperationPrivateKeys(...). None is exported; every copy was written by hand from the previous one.

Why it is worth recording

The helper encodes a cross-package convention, not a local detail: __-prefixed keys on an execution context belong to the operation plugin-security has in flight, and a consumer forwarding an envelope elsewhere must drop them. The producer of that convention is packages/plugins/plugin-security (security-plugin.tssc.__readScope = …, __writeScope, the ADR-0090 D10 delegator halves, plus the engine's __expandRead / __referentialFieldClear markers). The rule about how to consume it lives in three copies in three other packages, and the package that produces the keys owns none of them.

Consequences, all latent today:

  • A fourth consumer (any service that forwards a caller envelope to a gate or a read) is written by copy-paste or not at all, and nothing points a new author at the convention.
  • If the middleware ever stamps something operation-private without a __ prefix, three files have to change and there is no list of them.
  • Each copy's doc block reasons about its own package's object (sys_comment, sys_attachment, report.object_name), so the copies have already diverged in prose while agreeing in code — the shape that makes a later divergence in code hard to notice.

Why observation-class, not a defect

Nothing a user hits: all three copies are byte-equivalent in behaviour today, and each is covered by its own package's tests. This is a structural/ownership finding, so it carries finding and no pm:queue — grading is triage's call.

What I could not establish

Where the shared home should be. The candidates are not equivalent and the choice is a real one: @objectstack/spec (a constant + a pure function, but Prime Directive #2 says no business logic there — a key-filtering function may or may not count), @objectstack/core, or an export from plugin-security itself (the producer, which is the most honest owner but makes three packages depend on the security plugin for a string-prefix filter). Worth a decision rather than a guess.

Dedup

Searched open issues for withoutOperationPrivateKeys, __readScope + prefix/strip, and operation-private + envelope + helper/duplicate: no hits. #7141, #7145 and #7204 are the three landing sites and each is scoped to its own package; none of them covers the extraction.

Related: #7141, #7145, #7204, #6523, #6206 (ruling).


Generated by Claude Code

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions