Airlock

 view release on metacpan or  search on metacpan

.claude/agents/airlock-release-manager.md  view on Meta::CPAN

---
name: airlock-release-manager
description: "Owns Airlock's commits and release readiness — cuts commits from the worker's commit-ready tree, writes commit messages and Changes entries, moves karr cards to done. Release audit before CPAN release: cpanfile deps declared and pinne...
model: sonnet
briefing:
  skills:
    - getty-git-commit-style
    - getty-perl-release-author-getty
    - perl-release-dist-ini
    - airlock-core
    - kanban-issues-karr-ticket
---

You are the airlock-release-manager for **Airlock**. Conventions from the skills above are non-negotiable — apply silently.

**Commits.** You are the only role that commits. Read `git status`, `git diff` and the
worker's report; cut one commit per logical change and write the messages. Stage by

.claude/rules/airlock-rules.md  view on Meta::CPAN


Apply to every task in this repository unless explicitly overridden. Bias: caution over
speed on non-trivial work; use judgment on trivial tasks. Loaded automatically at launch
(same priority as `CLAUDE.md`). Subagents get their discipline from skills force-loaded via
`briefing.skills` — this file is for the orchestrating agent.

## Engineering discipline

1. **Think before coding** — state assumptions. When uncertain, ask rather than guess.
2. **Simplicity first** — minimum code that solves the problem; nothing speculative.
3. **Surgical changes** — touch only what you must; match existing style.
4. **Tests verify intent, not just behavior** — reproduce a bug before fixing it; leave a
   regression test behind. A test that can't fail when the logic changes is wrong.
5. **Read before you write** — before new code, read the callers and the spec section the code belongs to (`docs/superpowers/specs/`).
6. **Surface conflicts, don't average them** — pick one pattern, explain why, flag the
   other for cleanup.
7. **Checkpoint after every significant step** — done / verified / left.
8. **Fail loud** — "done" is wrong if anything was skipped silently.

## Delegation

.claude/rules/airlock-rules.md  view on Meta::CPAN

  no codes/tokens/secrets in logs or events. A change that weakens one needs the
  maintainer, not a judgment call.
- **Live test hits a real Keycloak.** `t/90-live-keycloak.t` runs only with
  `TEST_AIRLOCK_KEYCLOAK_URL` set. Never enable it in a fanned-out or parallel context.
- **Test runner trap.** Plain `prove -l t/` is non-recursive; always use `prove -lr t` so
  subdir tests are never silently skipped.

## Perl specifics — reference, don't restate

Module loading, Moo patterns, dependency pinning, `[@Author::GETTY]` release metadata,
POD directives, and house style live in skills `getty-perl-core`, `getty-perl-moo`,
`perl-release-dist-ini`, `getty-perl-release-author-getty`, and `airlock-core` (force-loaded
for `airlock-*` agents). Do not duplicate that content here.

.claude/skilletor.json  view on Meta::CPAN

      "git": "https://github.com/Getty/skills.git",
      "ref": "main"
    },
    "karr": {
      "git": "https://github.com/Getty/karr.git",
      "ref": "main"
    }
  },
  "install": {
    "skills": [
      "getty-git-commit-style@getty",
      "getty-git-usage@getty",
      "getty-perl-core@getty",
      "getty-perl-moo@getty",
      "getty-perl-pod@karr",
      "getty-perl-release-author-getty@karr",
      "kanban-issues-karr-coordination@karr",
      "kanban-issues-karr-ticket@karr",
      "perl-release-dist-ini@getty"
    ]
  },

MANIFEST  view on Meta::CPAN

lib/Airlock/Upstream/Authentik.pm
lib/Airlock/Upstream/Keycloak.pm
misc/agent-context/.claude/agents/airlock-doc-writer.md
misc/agent-context/.claude/agents/airlock-release-manager.md
misc/agent-context/.claude/agents/airlock-test-writer.md
misc/agent-context/.claude/agents/airlock-worker.md
misc/agent-context/.claude/rules/airlock-rules.md
misc/agent-context/.claude/skilletor.json
misc/agent-context/.claude/skilletor.lock.json
misc/agent-context/.claude/skills/airlock-core/SKILL.md
misc/agent-context/.claude/skills/getty-git-commit-style/SKILL.md
misc/agent-context/.claude/skills/getty-git-usage/SKILL.md
misc/agent-context/.claude/skills/getty-perl-core/SKILL.md
misc/agent-context/.claude/skills/getty-perl-moo/SKILL.md
misc/agent-context/.claude/skills/getty-perl-pod/SKILL.md
misc/agent-context/.claude/skills/getty-perl-release-author-getty/SKILL.md
misc/agent-context/.claude/skills/kanban-issues-karr-coordination/SKILL.md
misc/agent-context/.claude/skills/kanban-issues-karr-coordination/references/cards.md
misc/agent-context/.claude/skills/kanban-issues-karr-coordination/references/claims.md
misc/agent-context/.claude/skills/kanban-issues-karr-coordination/references/config.md
misc/agent-context/.claude/skills/kanban-issues-karr-coordination/references/cross-board.md

misc/agent-context/.claude/agents/airlock-release-manager.md  view on Meta::CPAN

---
name: airlock-release-manager
description: "Owns Airlock's commits and release readiness — cuts commits from the worker's commit-ready tree, writes commit messages and Changes entries, moves karr cards to done. Release audit before CPAN release: cpanfile deps declared and pinne...
model: sonnet
briefing:
  skills:
    - getty-git-commit-style
    - getty-perl-release-author-getty
    - perl-release-dist-ini
    - airlock-core
    - kanban-issues-karr-ticket
---

You are the airlock-release-manager for **Airlock**. Conventions from the skills above are non-negotiable — apply silently.

**Commits.** You are the only role that commits. Read `git status`, `git diff` and the
worker's report; cut one commit per logical change and write the messages. Stage by

misc/agent-context/.claude/rules/airlock-rules.md  view on Meta::CPAN


Apply to every task in this repository unless explicitly overridden. Bias: caution over
speed on non-trivial work; use judgment on trivial tasks. Loaded automatically at launch
(same priority as `CLAUDE.md`). Subagents get their discipline from skills force-loaded via
`briefing.skills` — this file is for the orchestrating agent.

## Engineering discipline

1. **Think before coding** — state assumptions. When uncertain, ask rather than guess.
2. **Simplicity first** — minimum code that solves the problem; nothing speculative.
3. **Surgical changes** — touch only what you must; match existing style.
4. **Tests verify intent, not just behavior** — reproduce a bug before fixing it; leave a
   regression test behind. A test that can't fail when the logic changes is wrong.
5. **Read before you write** — before new code, read the callers and the spec section the code belongs to (`docs/superpowers/specs/`).
6. **Surface conflicts, don't average them** — pick one pattern, explain why, flag the
   other for cleanup.
7. **Checkpoint after every significant step** — done / verified / left.
8. **Fail loud** — "done" is wrong if anything was skipped silently.

## Delegation

misc/agent-context/.claude/rules/airlock-rules.md  view on Meta::CPAN

  no codes/tokens/secrets in logs or events. A change that weakens one needs the
  maintainer, not a judgment call.
- **Live test hits a real Keycloak.** `t/90-live-keycloak.t` runs only with
  `TEST_AIRLOCK_KEYCLOAK_URL` set. Never enable it in a fanned-out or parallel context.
- **Test runner trap.** Plain `prove -l t/` is non-recursive; always use `prove -lr t` so
  subdir tests are never silently skipped.

## Perl specifics — reference, don't restate

Module loading, Moo patterns, dependency pinning, `[@Author::GETTY]` release metadata,
POD directives, and house style live in skills `getty-perl-core`, `getty-perl-moo`,
`perl-release-dist-ini`, `getty-perl-release-author-getty`, and `airlock-core` (force-loaded
for `airlock-*` agents). Do not duplicate that content here.

misc/agent-context/.claude/skilletor.json  view on Meta::CPAN

      "git": "https://github.com/Getty/skills.git",
      "ref": "main"
    },
    "karr": {
      "git": "https://github.com/Getty/karr.git",
      "ref": "main"
    }
  },
  "install": {
    "skills": [
      "getty-git-commit-style@getty",
      "getty-git-usage@getty",
      "getty-perl-core@getty",
      "getty-perl-moo@getty",
      "getty-perl-pod@karr",
      "getty-perl-release-author-getty@karr",
      "kanban-issues-karr-coordination@karr",
      "kanban-issues-karr-ticket@karr",
      "perl-release-dist-ini@getty"
    ]
  },

misc/agent-context/.claude/skilletor.lock.json  view on Meta::CPAN

{
  "skills/getty-git-commit-style": {
    "source": "getty",
    "version": "local",
    "files": {
      "skills/getty-git-commit-style/.gitignore": "sha256:fc8e72cc019d4536c45df00567078e36003f1d7183747e03283549741c3424c9",
      "skills/getty-git-commit-style/SKILL.md": "sha256:959bed63af658dcec1abc3010a2a262d347851a8aae87d833736d065c0f9f863"
    }
  },
  "skills/getty-git-usage": {
    "source": "getty",
    "version": "local",
    "files": {
      "skills/getty-git-usage/.gitignore": "sha256:fc8e72cc019d4536c45df00567078e36003f1d7183747e03283549741c3424c9",
      "skills/getty-git-usage/SKILL.md": "sha256:9a4cdf50cc3991e16b2af8882175e8e9a4e27b40fd93605898348ed2db506630"
    }
  },

misc/agent-context/.claude/skills/getty-git-commit-style/SKILL.md  view on Meta::CPAN

---
name: getty-git-commit-style
description: Use when writing or amending a commit message in a Getty repository, including a commit that spans several repos.
---

# Commit Message Style

## Format

```
<summary line — imperative, max ~72 chars>

misc/agent-context/.claude/skills/getty-git-usage/SKILL.md  view on Meta::CPAN

---
name: getty-git-usage
description: "Use when committing, pushing, or landing work in a Getty repo — commit/push cadence, rebase vs merge, cleaning history before a PR, stacked branches, cutting a release. Commit wording: getty-git-commit-style."
---

# Git usage

Short version: **keep the history linear.** A branch lands rebased, not merged.

## Landing work

```bash
git fetch origin

misc/agent-context/.claude/skills/getty-git-usage/SKILL.md  view on Meta::CPAN

in every working tree linking it — as a change nobody made *here*. Commit it in this
repo too, on its own, never folded into a code commit: it is someone else's edit
passing through, and a shared commit would file it under a message that does not
describe it.

Conventional prefixes (`feat:`, `fix:`, `docs:`, `test:`, `ci:`, `chore:`, `refactor:`),
always `--signoff`. The prefix is not decoration where a release workflow reads it:
`feat:` cuts a minor, `fix:` a patch, `feat!:` or a `BREAKING CHANGE:` body a major.
Everything else cuts nothing.

Message wording, body structure and multi-repo commits: see `getty-git-commit-style`.

## Before pushing

Run whatever the repo uses to check itself — its test script, `bash -n`, `py_compile`.
CI is a safety net, not the first place a failure should surface.

Never rewrite history that is already on `main`.

misc/agent-context/.claude/skills/getty-perl-core/SKILL.md  view on Meta::CPAN


## Control flow

- **Postfix `if`/`unless`** for guards and short conditions: `croak(...) if $self->readonly;`
- **`unless $x`** instead of `if !$x`.
- **Guard clauses return bare:** `return unless $res->is_success;` — not `return undef;`.
- **Nested ternaries** for a return that picks between expressions, instead of an if/elsif chain.

## Data

- **`{ %hash }` and `\%hash` are different operations, not two styles.** `{ %h }` builds a new anonymous copy; `\%h` references the existing hash. Return a copy when the caller must not mutate your state; return the reference when sharing is the poin...
- **`Path::Tiny`** for every file operation — not `File::Spec`, not bare `open`. `path(...)->child(...)->slurp_utf8`.
- **`JSON::MaybeXS`** always — never `JSON::PP`, `JSON::XS`, `Cpanel::JSON::XS` directly. Encoders get `canonical => 1, convert_blessed => 1`.
- **Every serialiser is deterministic.** MessagePack `->canonical`, DBIC `serializer_options => { canonical => 1 }`. Same rule, every format.
- **Booleans: `JSON->true` / `JSON->false`.** `use JSON::MaybeXS;` covers codec and booleans.
- `$YAML::XS::Boolean = 'JSON::PP'` is one of YAML::XS's fixed mode names, not a module choice — leave it alone.
- **Align `=>` in multi-line hash literals** when keys are of similar length.
- **Optional pairs inline:** `$cond ? ( experimental => 1 ) : (),`

## Configuration

misc/agent-context/.claude/skills/getty-perl-moo/SKILL.md  view on Meta::CPAN

- Moose class can `extends` a Moo class
- Moo class can `with` a Moose role

```perl
BEGIN { require Moose }
package MyMooseClass;
use Moose;
extends 'MyMooClass';   # works if Moose was loaded first
```

For Moose-style syntax in Moo (`isa => 'Str'`, `lazy_build`), use `MooX::late`. Avoid `Any::Moose` – deprecated, points to Moo.

---

## Type Constraints

Moo has no built-in type system — `isa` takes a coderef, and `Type::Tiny` objects
are coderefs, so `Types::Standard` plugs straight in:

```perl
use Types::Standard qw( Str ArrayRef );

misc/agent-context/.claude/skills/getty-perl-moo/SKILL.md  view on Meta::CPAN


| Situation | Use |
|---|---|
| Shared attributes/methods, stable "is-a" | `extends` |
| Optional/horizontal feature | `Moo::Role` + `with` |
| Same pattern, different config | `MooX::Role::Parameterized` |
| Delegate method set to sub-object | `handles` |
| Array/Hash operations on attribute | `Sub::HandlesVia` |
| Logging/validation/caching wrapper | `before`/`around`/`after` |
| Catch constructor typos | `MooX::StrictConstructor` |
| Cross-project boilerplate | `Import::Into` house-style module |
| Named types | `Type::Tiny` / `Types::Standard` |
| Multiple roles define same method | Sequential `with` or refactor |
| Legacy non-Moo parent | `FOREIGNBUILDARGS` |
| Multiple inheritance | Last resort; use `mro 'c3'` |

---

## Common Pitfalls

- `default => []` → **shared state bug**. Always `default => sub { [] }`.

misc/agent-context/.claude/skills/getty-perl-release-author-getty/SKILL.md  view on Meta::CPAN

version); running `dzil release` is not. Never run it on your own initiative, and never
treat your own offer to run it as a yes — only an explicit instruction from the
maintainer to release is authorization; absent that, you never assume it.

```bash
dzil release        # Builds, tests, uploads to CPAN, bumps version, commits, tags
```

Read the `{{$NEXT}}` section of `Changes` once as a whole first. It was written bullet
by bullet over weeks, so this is where entries circling one topic get merged into one
and over-detailed ones get cut back (skill `getty-git-commit-style`). It is not only a
changelog: `GitHub::CreateRelease` runs with `notes_from = ChangeLog` and publishes the
section verbatim as the release notes.

Fix it in its own commit *before* `dzil release`. `Changes` sits in the release commit's
`allow_dirty` list, so an uncommitted edit stops nothing — it is folded into the release
snapshot silently, under a message naming only the version.

## Conventions

1. `copyright_year` IS used in dist.ini — GETTY has it in ALL distributions, do NOT remove it



( run in 2.008 seconds using v1.01-cache-2.11-cpan-b554fb43c41 )