Group the gateway's data-plane modules into three service sub-packages
mirroring the host-side trio (bot_bottle.egress / .supervisor / .git_gate):
gateway/egress/ addon_core, addon, dlp_config, dlp_detectors
gateway/supervisor/ server (was supervise_server)
gateway/git_gate/ render, http_backend
Prefix-stripped filenames now that the package namespaces them; each
sub-package has a thin docstring __init__ (no eager imports, cheap leaf
loads). The two cross-cutting files stay at the gateway root:
policy_resolver (shared per-client lookup) and gateway_init, renamed to
bootstrap now that gateway/ already namespaces it.
Updated all importers (bot_bottle + tests), the in-VM/container `-m`
launch strings, the Dockerfile.gateway addon shim + ENTRYPOINT, and the
five gateway entries in scripts/critical-modules.txt. Full unit suite
green (2243).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
git_gate.py (699 LOC) mixed three responsibilities. Split into:
- git_gate_render.py — pure host-side rendering: the gate constants,
GitGateUpstream, gitconfig/known-hosts rendering, and the entrypoint /
pre-receive / access-hook script builders.
- git_gate_provision.py — the gitea deploy-key lifecycle
(_provision_dynamic_key / revoke / _resolve_identity_file).
- git_gate.py — the GitGate ABC + GitGatePlan, now 169 LOC, re-exporting
all moved names (see __all__) so the 19 importers are unchanged.
Host-side only (not flat-bundled), so no sidecar import shim. The one
test that patched the internal `_provision_dynamic_key` lookup is
repointed to its new module (public API unchanged). The two new modules
are added to scripts/critical-modules.txt so the decompose doesn't move
security code out of the measured core — critical aggregate stays 95%
(git_gate 100%, render 100%, provision 97%).
Closes#303
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NkwFXLFff9PYPy4wgVBJp9
Surface the metric ADR 0004 says matters — the critical security/logic
core, currently 95% — as a README badge, distinct from the
informational global `coverage` badge.
- scripts/critical-modules.txt: single source of truth for the core
module list. scripts/coverage.sh now reads it (instead of a hardcoded
string) and update-badges.yml reads the same file, so the badge and
the `critical` report cannot drift.
- update-badges.yml: a `core coverage` step reuses the unit-coverage
data (every core module is unit-tested, so unit-only is accurate for
it) and sed-updates the new badge, like the existing ones.
- README: `core coverage 95%` badge linking to ADR 0004 so a reader can
find out what "core" means.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NkwFXLFff9PYPy4wgVBJp9