Skip to content

Design: org-level config with locked settings, and scoped org memory #169

Open

Description

@exactml

Context

Companies have hundreds of repos. Today every repo's .marginal/ stands alone: each one copies the security policy, each one picks its own threshold, and a lesson learned in one repo (e.g. "internal service URLs like http://payments.internal aren't secrets, don't flag them") has to be re-learned in every other. An org needs two things: settings and policies set once, some of them enforced, and shared memory of decisions that applies wherever it's relevant.

Proposal: one org repo, one way of loading it

Where: a repo named <org>/.marginal, following GitHub's <org>/.github convention. It's versioned, changes go through PRs, and no new infrastructure is needed.

acme/.marginal/
├── config.yaml        # org defaults + locked settings
├── policies/          # always-on org policies
└── memory/            # curated decisions, each scoped by path

Org config with locked settings. Layers are built-in defaults → org config → repo config (read from the PR's base commit, #151). The org can lock a setting so repos may tighten it, never loosen it:

# acme/.marginal/config.yaml
review:
  max_comments: 8
policies: [policies/security.md]
locked:
  review.max_comments: {max: 8}             # a repo may lower it, never raise it
  policies: [policies/security.md]          # always applied, can't be removed

Org memory, curated and scoped. Each file says which code it applies to. At review time marginal loads only the entries whose paths match the PR, so prompts don't grow with the org:

---
applies_to: ["config/**", "deploy/**"]
---
Internal service URLs (`http://payments.internal`, `http://search.internal:9200`)
are hostnames, not credentials (auth comes from the environment). Don't flag them
as secrets. Do flag a URL with credentials inside it (`https://user:pass@host`).

People approve every entry through a PR. A future insights command proposes entries from repeated disputes. Raw history (every finding and its outcome) stays in the audit store (#163), owned by the shared UI server (#168). It's the input for proposals, and it's never loaded straight into prompts.

Design questions

  1. Access: in Actions, GITHUB_TOKEN can only read its own repo. Options: a public <org>/.marginal (fine if it holds no secrets), or an org-config-token input on marginal-action backed by a GitHub App token. Recommendation: GitHub App.
  2. Which settings can be locked, and how each one locks: min/max for numbers, "always included" for lists, a fixed value for booleans.
  3. Matching memory: path globs only to start? Add topic tags later? What's the cap on entries per review, and which win when over it?
  4. Org vs repo conflicts: can a repo anti-policy contradict an org memory entry, and which wins?
  5. Caching: fetch the org repo once per run, keyed by its commit SHA.
  6. Visibility: marginal doctor and the UI (Local marginal UI for review audits and config (like MLflow tracking) #167) show each final setting and the layer it came from, e.g. max_comments: 8 (org, locked).

Acceptance criteria

  • A design comment answers the questions above.
  • Implementation issues are split out: locked-config schema and merge, fetching the org repo, scoped memory loading, and doctor/UI display.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions