Skip to content

Allowlist sync: expand one entry across equivalent command prefixes (bare ↔ rtk ↔ chezmoi) #37

Description

@nickvigilante

Problem

Equivalent invocations of the same underlying program each need their own allowlist entry today, and maintaining them by hand drifts — exactly what bit us with the rtk-rewrite mirrors (#26, #32):

  • gh pr list vs rtk gh pr list
  • git log vs rtk git log vs chezmoi git log vs git -C * log
  • cargo tree vs rtk cargo tree

Desired behavior

Write a read/deny verb once per program and have every equivalent prefix form emitted automatically. Adding gh pr list should also yield rtk gh pr list; adding chezmoi git log should also yield bare git log, rtk git log, git -C * log; cargo treertk cargo tree.

Model: prefix-equivalence groups

Define groups keyed by the underlying program:

  • git group: git, git -C *, rtk git, chezmoi git
  • gh group: gh, rtk gh
  • cargo group: cargo, rtk cargo
  • generally, every rtk-wrapped program E{ E, rtk E }, plus extra aliases where they exist (git's -C form and chezmoi passthrough).

A build step fans each verb across its group's prefixes. Deny verbs fan out identically (e.g. branch -d/-D/--delete across the whole git group — today only git/rtk git are mirrored).

Canonical-source vs any-form (the bidirectionality ask)

  • Option 1 — canonical source (recommended): the source list is written in one canonical form (bare verb per group): git: [log, diff, …], gh: [pr list, …]. Prefixes come from the group definition; you never hand-write mixed forms.
  • Option 2 — any-form input (the literal ask): accept an entry in any prefix, normalize by stripping a known prefix to recover program+verb, then expand to the whole group. Nicer ergonomics, more logic (prefix detection/normalization). Suggest shipping Option 1 first; Option 2 is a thin layer on top later.

Mechanism (the open question)

  • (a) Pure chezmoi template — verb lists + groups in [data] / .chezmoidata/*.toml, consumed by settings.json.tmpl. Native, but Go-template JSON assembly with trailing-comma handling is fiddly (DRY up git permission rules: chezmoi-template one verb list across git / git -C / rtk git / chezmoi git #32 already notes "build the list and toJson it").
  • (b) Data + run_onchange_ script (recommended) — data in .chezmoidata (or a standalone YAML/TOML); a run_onchange_ jq/python script reads it, computes the cross-product, and writes the permissions.allow/permissions.deny arrays. Real data structures + jq make expansion and validation robust; reruns on data-hash change.
  • Either way: a render check that chezmoi cat ~/.claude/settings.json | jq . parses — a template/script bug must not silently break all permissions.

Critical constraint: don't clobber the live rtk hook

rtk hook claude writes its PreToolUse hook into the live ~/.claude/settings.json (see the drift note in the chezmoi skill). The generator must own only the permissions.allow / permissions.deny arrays and merge rather than overwrite the file, so it never wipes the live hook block (or theme, enabledPlugins, etc.).

Relationship

This is the general engine. #32 is the first concrete instance (git + rtk-wrapped providers) and would be reimplemented on top of this. #36 (non-rtk tools) is single-prefix (bare-only group) — no fan-out needed, but it can share the same source list.

Acceptance

  • A single source edit (one verb under one program) produces all equivalent prefix entries on chezmoi apply.
  • Deny verbs fan out across the full group.
  • jq parses the rendered settings.json.
  • The live rtk hook claude block and other live keys survive a re-render.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions