feature-flags-audit-426af3 — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited feature-flags-audit-426af3 (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Produce a synthetic inventory of every feature flag declared in the Packmind codebase, with audience targeting, inferred functional descriptions, and orphan detection. The result is a single markdown table the user can scan at a glance.
Packmind uses a custom, frontend-only feature flag system. There is no third-party library (LaunchDarkly, GrowthBook, PostHog, etc.). Flags are gated by email domain or exact email via a single central registry. There is no org-based, plan-based, percentage-rollout, or runtime-override mechanism — what's in the registry file is what's live in production.
Canonical source of truth: packages/ui/src/lib/components/content/PMFeatureFlag/PMFeatureFlag.tsx
This file exports:
_FEATURE_KEY (e.g. SPACES_MANAGEMENT_FEATURE_KEY = 'spaces-management').DEFAULT_FEATURE_DOMAIN_MAP: a Record<string, readonly string[]> mapping each flag's string value to a list of allowed entries. Entries starting with @ are domain rules (e.g. @packmind.com matches any user at that domain). Entries containing @ but not starting with @ are exact email matches.PMFeatureFlag React wrapper component and the isFeatureFlagEnabled() pure function used at call sites.If a flag is not declared in DEFAULT_FEATURE_DOMAIN_MAP, it does not exist. Do not invent flags.
Read packages/ui/src/lib/components/content/PMFeatureFlag/PMFeatureFlag.tsx. Extract:
_FEATURE_KEY, along with its string value. The string value is what appears as a key in DEFAULT_FEATURE_DOMAIN_MAP — keep the mapping (constant name ↔ string value) in memory.DEFAULT_FEATURE_DOMAIN_MAP object. For each entry, record the flag's string value and its list of allowed domains/emails.Build an internal list of flags with three fields so far: constant name, string value, audience (array of allowed entries).
Cross-check constants against the map. Every _FEATURE_KEY constant should have a matching entry in DEFAULT_FEATURE_DOMAIN_MAP, and every map entry should correspond to a declared constant. A mismatch is a real misconfiguration:
If you find either case, do not drop it from the inventory — include it and surface the mismatch in the Summary section.
For each flag, search the codebase for where it is consumed. Use Grep:
SPACES_MANAGEMENT_FEATURE_KEY). This is the canonical import form and catches almost all usages.'spaces-management' or "spaces-management") as a safety net. Some usages may inline the string instead of importing the constant.Scope the search to:
apps/frontend/src/**apps/frontend/app/** — the React Router v7 file-based route tree. Route modules live here (e.g. apps/frontend/app/routes/org.$orgSlug._protected.settings.tsx), not under src/, and they gate flags too (typically via isFeatureFlagEnabled(...) to show/hide nav entries, routes, or whole pages). Omitting this directory will mis-report a live route-gated flag as an orphan.packages/**Exclude:
packages/ui/src/lib/components/content/PMFeatureFlag/PMFeatureFlag.tsx.PMFeatureFlag.test.tsx. (The parent barrel at packages/ui/src/lib/components/content/index.ts only re-exports the component and does not reference any _FEATURE_KEY, so it won't appear in the search — no explicit exclusion needed.)*.test.*, *.spec.*, and Storybook stories *.stories.*. A usage inside a test doesn't represent shipping behavior and would mislead a reader scanning the "Usage files" column. If a flag is only referenced from tests, treat it as an orphan (see Step 4) and note the test-only state in the description.dist/, node_modules/).Record the list of files where each flag is actually consumed.
For each flag with at least one usage, open 1 to 3 of the most representative usage files and read enough context to understand what the flag actually gates from a user-facing perspective. Use these signals (in rough priority order):
<PMFeatureFlag featureKeys={[FLAG]}>...</PMFeatureFlag> — this is literally what appears or disappears.isFeatureFlagEnabled({ featureKeys: [FLAG] }) — often an "edit" / "create" / "delete" affordance, or an entire route/tab.SpacesManagementActions.tsx → space management actions).Write one short sentence in the functional voice — describe what the user sees (or doesn't see) when the flag is off. Avoid technical framing.
Examples of good descriptions:
Examples of bad descriptions (do not write these):
PMFeatureFlag component in SpacesManagementActions.tsx." (tells the reader nothing functional)If you cannot form a confident one-liner after reading the usage sites, write a shorter description prefixed with (uncertain) so the user knows to double-check.
For each flag, search apps/e2e-tests/src/ for spec files that call .use({ underFeatureFlag: true }). These tests explicitly target a feature-flagged flow and represent intentional E2E coverage of the flag.
grep -r "underFeatureFlag: true" apps/e2e-tests/src/Record which flags have associated E2E test coverage. A flag with no E2E coverage is not an orphan (orphan is determined by frontend usage, not tests), but the information is worth surfacing so the user knows which flagged features are tested end-to-end.
Add an E2E tested column to the output table (Step 5) with either Yes or No.
A flag is orphan if, after the two-pass search, no usage is found outside the canonical file and its test. Orphans are candidates for removal and worth surfacing — they often accumulate when a feature ships and nobody remembers to delete the gate.
Before declaring a flag orphan, confirm the search covered `apps/frontend/app/ (the route tree), not just apps/frontend/src/`. A flag is frequently consumed only in a route module to gate a nav entry or page — missing that directory is the most common cause of a false orphan.
For orphans:
Orphan.(no usage found — candidate for removal).—.Output a single markdown table. Use these columns, in this order, with these exact headers:
| Key | Audience | Functional description | Status | E2E tested | Usage files |
Column rules:
change-proposals), not the constant name. It's what appears in the domain map and what a PM or stakeholder recognises.@ prefix). If the list is empty, write (none).Active or Orphan.Yes if at least one spec file in apps/e2e-tests/src/ uses .use({ underFeatureFlag: true }), otherwise No.(… +N more) if there are more. "Most representative" is a ranked preference, in this order:<PMFeatureFlag featureKeys={[FLAG]}>...</PMFeatureFlag> JSX gate — these are the literal "what appears when the flag is on".isFeatureFlagEnabled({ featureKeys: [FLAG] }) in a branch that guards an action, route, or tab.For orphans, write —.
After the table, add a short Summary section with:
@monpetitplacement.fr, @ninaa.io) is usually a pilot and the user will want to notice it. Mention it briefly.# Feature Flags Inventory
| Key | Audience | Functional description | Status | E2E tested | Usage files |
| --- | --- | --- | --- | --- | --- |
| space-identity | @packmind.com, @promyze.com | Reveals the space identity settings panel and related configuration affordances. | Active | No | apps/frontend/src/domain/spaces/components/SpaceGeneralSettings.tsx, apps/frontend/src/domain/spaces/components/SpaceIdentityForm.tsx |
| change-proposals | @packmind.com, @promyze.com, @monpetitplacement.fr, @ninaa.io | Enables the change proposal review flow end-to-end (navigation entry points and review detail pages). | Active | Yes | apps/frontend/src/domain/change-proposals/components/StandardReviewDetail/StandardReviewDetail.tsx, apps/frontend/src/domain/change-proposals/components/SkillReviewDetail/SkillReviewDetail.tsx, apps/frontend/src/domain/change-proposals/components/CommandReviewDetail/CommandReviewDetail.tsx (… +2 more) |
| some-old-flag | @packmind.com | (no usage found — candidate for removal) | Orphan | No | — |
**Summary:** 7 flags — 6 active, 1 orphan. `change-proposals` is opened to `@monpetitplacement.fr` and `@ninaa.io` (external pilots, worth monitoring).Output only the report — no preamble, no "here is the table" sentence. The user invokes this skill to get the report itself.
DEFAULT_FEATURE_DOMAIN_MAP are real flags. If the user asks about a flag that isn't there, say so explicitly.@packmind.com means "any user whose email is at this domain", nothing more.apps/api/, apps/mcp-server/, or apps/cli/. If you ever find a _FEATURE_KEY import there, flag it as unusual — it would be a violation of the established pattern.apps/frontend/src/, but React Router v7 route modules live in apps/frontend/app/routes/. Flags are gated in both. Searching only src/ is the classic miss — e.g. MARKETPLACES_FEATURE_KEY is consumed solely in apps/frontend/app/routes/org.$orgSlug._protected.settings.tsx to gate the Settings → Distribution → Marketplaces nav entry, and would look like an orphan if app/ were skipped.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.