Skip to content

feat(content-lane): resolve RegistryLaneSpec per-repo from .gittensory.yml config #2435

Description

@JSONbored

Context

Final issue in the chain making the content-lane registry-review engine reusable by any self-hosted maintainer's own registry repo (follows #2433 and #2434; tracked under the parent roadmap). This is the concrete gap-closer: today, exactly one repo's RegistryLaneSpec is compiled into gittensory and hard-selected at the single call site that wires the content lane into the live gate. Every allowlisted repo gets that same spec, unconditionally. A second maintainer wanting to use this engine for their own registry would need to add a new spec constant to gittensory's own source and edit the hard-coded call site — i.e. a gittensory code change and redeploy, not a config change on their own self-hosted instance. That directly contradicts this repo's own "modular & config-driven, never hard-coded for one repo" principle (see the parent roadmap issue and CONTRIBUTING.md's config-as-code section).

This closes it by making per-repo RegistryLaneSpec selection follow the exact same config-resolution pattern already used for the other per-repo "converged features" (see src/review/feature-activation.ts's resolveConvergedFeature and its precedence: env kill-switch → per-repo .gittensory.yml override → allowlist default) — reusing existing, proven plumbing rather than inventing a new one.

Requirements

  • Add a new .gittensory.yml config block for content-lane registry configuration, with fields for: which files count as an entry submission / an optional companion provider file / an optional generated-artifact companion (as bounded glob patterns — not raw regular expressions; compile them via the existing glob-to-pattern compiler already used for guardrail path matching in src/signals/change-guardrail.ts, to avoid ever compiling a maintainer-supplied string as an unbounded regex), which array field on the entry file holds appended entries, an optional cap on how many entries one PR may append, an optional set of fields used for duplicate-entry detection, and an optional named reference to a registered domain validator (from refactor(content-lane): inject registry validators via RegistryLaneSpec instead of hardcoded imports #2434's injection point).
  • Add a small, code-reviewed registry mapping validator names to the validator-callback pairs from refactor(content-lane): inject registry validators via RegistryLaneSpec instead of hardcoded imports #2434, seeded with our own repo's existing validator so its behavior is unchanged.
  • Add a resolver (mirroring resolveConvergedFeature's precedence shape) that returns the effective RegistryLaneSpec for a given repo: env kill-switch off → inactive; explicit per-repo config present → build a spec from it; otherwise → today's allowlist-based default (so zero-config behavior for our own repo is unchanged).
  • Wire content-lane-wire.ts's host adapter to use the resolved spec instead of the single hard-coded spec constant.
  • Reconcile with the existing flag + allowlist gate (isContentLaneWired / the per-repo cutover allowlist) so there's exactly one source of truth for "is the content lane active for this repo, and with which spec" — no path where the two checks could disagree.
  • Remove/update the code comment that currently says this exact capability is deferred as "a follow-up" — this issue is that follow-up.
  • Document the new .gittensory.yml block wherever the other config-as-code blocks (gate: / settings: / features:) are already documented for self-hosted maintainers.
  • No database migration is required or wanted for this — this is a .gittensory.yml-only feature, matching how the other per-repo "converged features" already work (no dashboard UI exists for this today, and none is being added here).

Deliverables

  • New .gittensory.yml schema block for per-repo content-lane/registry configuration (glob-based file patterns, entry-count cap, dedup fields, named validator reference).
  • Glob fields compiled via the existing glob compiler, never a raw regex-from-config.
  • Small code-registered validator-name → validator-callback-pair map, seeded with our own repo's existing validator.
  • A resolver function with env → per-repo-config → allowlist-default precedence, returning the effective spec (or "inactive").
  • content-lane-wire.ts consumes the resolved spec; the old single hard-coded spec constant is no longer referenced there.
  • The two existing gating checks (flag/allowlist vs. new resolver) reconciled into one source of truth.
  • Stale "deferred as a follow-up" code comment removed.
  • New config block documented for self-hosted maintainers.
  • Tests: precedence tests (env-off, allowlist-only-default, explicit-config-override, unregistered-validator-name-degrades-gracefully) plus a test proving a synthetic second repo can activate the surface lane end-to-end purely from .gittensory.yml config, with no gittensory source change — this is the concrete proof the gap is closed.
  • Full unsharded coverage + npm run test:ci green.

Expected outcome

A self-hosted maintainer running their own gittensory instance over their own registry-style repo can enable deterministic, AI-free structured-data review for it by adding a .gittensory.yml block to their own repo — no gittensory fork, no source edit, no redeploy. Our own repo's behavior is unchanged (it keeps using its existing spec via the allowlist-default fallback unless we explicitly opt it into the new config path).

Metadata

Metadata

Assignees

Labels

maintainer-onlyOwner-only work — yields no Gittensor points.

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions