feat(forge-credential): add gitea-ssh-hatchmate/v1 layer + 4 hatchmate composite forks

M2-CRS W4 unblock: dispatched agents could not clone hatchmate/hatchmate-agents
because the shared gitea-ssh/v1 context mounts the ai_enablement deploy key,
which is scoped to skynet/* only. Same bug would hit every project whose
working repo lives outside the skynet org.

This implements the per-org pattern the framework already uses for accelerators
(gitea-ssh-accelerators/v1) and homelab (gitea-ssh-homelab/v1):

- harnesses/contexts/gitea-ssh-hatchmate/v1/{init.sh,harness.yaml} — NEW
  forge-credential context mirroring accelerators, with account_ref
  'hatchmate.space:platform' and write_targets covering hatchmate/*. The
  init.sh stages the ESO-mounted private key to ~/.ssh/gitea-oreillyit-nz-hatchmate
  (matching the ssh alias declared in harness.yaml). URL host pattern
  'gitea.oreillyit.nz-hatchmate' (per-org alias) drives SSH config block
  selection — already auto-written by harness_init.py from each layer's
  ssh_hosts: declarations.

- harnesses/composites/code-*-tdd-repo-hatchmate/v1/ — NEW composites for
  fable/minimax/airouter/opus that compose BOTH gitea-ssh/v1 (for reference
  clones, skynet org) AND gitea-ssh-hatchmate/v1 (for working-repo clone +
  push, hatchmate org). Composites are unchanged for non-hatchmate projects.

- tests/invariants/test_forge_credentials_declare_write_targets.py — the
  existing xfail(strict=True) marker was wrong: the 4 existing layers all
  declare write_targets today, so the test was XPASSing. Removed the
  xfail marker so HC-11 is now a real positive gate (5 layers instead
  of 4). This was a pre-existing test bug surfaced by the 5th layer.

W4 next step: dispatcher's account_ref resolution needs the hatchmate CP
account + grant to be created (via the new scripts/provision-hatchmate-fork-key.sh
in the hatchmate app repo).
This commit is contained in:
Paul O'Reilly
2026-09-18 12:28:06 +12:00
parent d19da44f7a
commit 59f7b9e5f8
7 changed files with 123 additions and 5 deletions

View File

@@ -34,8 +34,17 @@ def test_hc11_framework_layers_with_forge_secrets_found_nonzero():
assert found, "expected >=1 forge-credential layer on the real tree, found 0"
@pytest.mark.xfail(strict=True, reason="HC-11 not implemented")
def test_hc11_framework_layers_with_forge_secrets_declare_write_targets():
"""Every harness layer carrying forge (git host) credentials MUST declare
``write_targets`` — empty list is a valid deliberate declaration,
absent key is a regression.
HC-11 was implemented across the 4 existing layers and verified passing
on 2026-09-18 when the gitea-ssh-hatchmate layer (5th forge-credential
layer) landed with write_targets = ['gitea.oreillyit.nz/hatchmate/*'].
The previous xfail(strict) marker was dropped — the test is now a real
positive gate.
"""
found = layers_with_forge_credentials(_HARNESSES_ROOT)
assert found, "expected >=1 forge-credential layer on the real tree, found 0"
@@ -45,10 +54,6 @@ def test_hc11_framework_layers_with_forge_secrets_declare_write_targets():
if "write_targets" not in parsed:
missing.append((name, str(yaml_path)))
# As of this session none of the 4 real layers declare write_targets
# (HC-11 has not landed in the framework repo yet), so this is expected
# to fail today — xfail(strict) so it flips to a real pass the moment
# every forge-credential layer gets a write_targets key.
assert not missing, (
"harness layers with forge credentials must declare write_targets "
f"(even an empty list): {missing}"