Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .claude/skills/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Reusable, task-focused instruction packs ("skills") for AI coding agents working on **LearnStack Hub**. Each subdirectory is one skill; its `SKILL.md` carries YAML frontmatter (`name`, `description`) so the agent runtime can pick or skip it without reading the whole body.

Skills are **project-local** to this repo (`.claude/skills/`). An agent running from the `learnstack-hub` root loads them automatically. They cite LearnStack core's standards / ADRs by sibling path (`../learnstack/docs/...`) for cross-cutting authority and carry only the **Hub-specific delta** on top — they never duplicate the LearnStack standards corpus.
Skills are **project-local** to this repo (`.claude/skills/`). An agent running from the `learnstack-hub` root loads them automatically. They cite LearnStack core's standards / ADRs by sibling path (`../LearnStack/docs/...`) for cross-cutting authority and carry only the **Hub-specific delta** on top — they never duplicate the LearnStack standards corpus.

## The Hub deltas every skill assumes

Expand Down Expand Up @@ -38,7 +38,7 @@ Pick the entry point matching the user's intent. Only **one** entry point runs p
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| [implement-task](implement-task/SKILL.md) | The default entry point for substantive work — scope, implement, self-check, test, docs, commit, review prompt. |
| [start-task](start-task/SKILL.md) | Lightweight scoping-only entry point. Reading order + alignment check. |
| [write-adr](write-adr/SKILL.md) | Capturing a **Hub-internal** decision (`HUB-NNNN` series). Cross-cutting decisions go in `../learnstack/docs/decisions/`. |
| [write-adr](write-adr/SKILL.md) | Capturing a **Hub-internal** decision (`HUB-NNNN` series). Cross-cutting decisions go in `../LearnStack/docs/decisions/`. |
| [update-glossary](update-glossary/SKILL.md) | Introducing a Hub-specific term in `docs/glossary.md`. |
| [commit-and-pr](commit-and-pr/SKILL.md) | Conventional Commit + AI trailer + Hub PR conventions (incl. cross-repo coordination). |

Expand Down Expand Up @@ -102,6 +102,6 @@ Body structure: **Purpose**, **When to use** / **When not to use**, **Inputs**,

## What skills are not

- **Not duplicates of standards.** A skill is a _workflow_. LearnStack's [Standards corpus](../../../learnstack/docs/standards/) is the authority; skills cite it.
- **Not decisions.** Decisions live in ADRs (LearnStack `../learnstack/docs/decisions/` for cross-cutting; this repo's `docs/decisions/` for `HUB-NNNN`).
- **Not duplicates of standards.** A skill is a _workflow_. LearnStack's [Standards corpus](https://github.com/HodeTech/LearnStack/blob/main/docs/standards/) is the authority; skills cite it.
- **Not decisions.** Decisions live in ADRs (LearnStack `../LearnStack/docs/decisions/` for cross-cutting; this repo's `docs/decisions/` for `HUB-NNNN`).
- **Not scratch space.** Exploratory notes go in `docs/analysis/` (gitignored).
2 changes: 1 addition & 1 deletion .claude/skills/add-architecture-test/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Make a structural rule mechanical + non-skippable. Hub's architecture suite is t

## The Hub architecture-test set

The tests `LearnStack.Hub.Tests.Architecture` should carry as P02c-1 lands modules (authoritative list: [Architecture 24 § 10](../../../../learnstack/docs/architecture/24-learnstack-hub.md), Hub-side):
The tests `LearnStack.Hub.Tests.Architecture` should carry as P02c-1 lands modules (authoritative list: [Architecture 24 § 10](https://github.com/HodeTech/LearnStack/blob/main/docs/architecture/24-learnstack-hub.md), Hub-side):

| Test | Asserts |
| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
Expand Down
2 changes: 1 addition & 1 deletion .claude/skills/add-ef-migration/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ description: >

## Purpose

Produce a migration that follows Hub's database conventions: `hub` schema, snake_case, the right index/constraint naming, JSONB for dictionaries, **no RLS** (the load-bearing difference from LearnStack's migrations) and the forward-only / two-step destructive rules from [Standards 05](../../../../learnstack/docs/standards/05-database.md).
Produce a migration that follows Hub's database conventions: `hub` schema, snake_case, the right index/constraint naming, JSONB for dictionaries, **no RLS** (the load-bearing difference from LearnStack's migrations) and the forward-only / two-step destructive rules from [Standards 05](https://github.com/HodeTech/LearnStack/blob/main/docs/standards/05-database.md).

## When to use

Expand Down
6 changes: 3 additions & 3 deletions .claude/skills/add-feature-key/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ Hub is the **authoring** side of entitlements: operators build plans whose `feat

- Reading a flag at runtime → that's LearnStack core's `IFeatureFlags.IsEnabledAsync`, not Hub. Hub never _reads_ entitlements for gating; it _authors_ them.
- Per-request toggling → forbidden; entitlements are plan-projected.
- A domain-flavoured key (`english.placement`, `yoga.asana`) → forbidden; keys are generic platform capabilities ([ADR-0021](../../../../learnstack/docs/decisions/0021-feature-based-entitlement.md)).
- A domain-flavoured key (`english.placement`, `yoga.asana`) → forbidden; keys are generic platform capabilities ([ADR-0021](https://github.com/HodeTech/LearnStack/blob/main/docs/decisions/0021-feature-based-entitlement.md)).

## Workflow

### Step 1 — Confirm shape + naming

Per [ADR-0021 Amendment 1](../../../../learnstack/docs/decisions/0021-feature-based-entitlement.md) + [entitlement-projection.md § key-shape rules](../../../docs/architecture/entitlement-projection.md):
Per [ADR-0021 Amendment 1](https://github.com/HodeTech/LearnStack/blob/main/docs/decisions/0021-feature-based-entitlement.md) + [entitlement-projection.md § key-shape rules](../../../docs/architecture/entitlement-projection.md):

- `FeatureKey` value: dotted snake_case, **no `.enabled` suffix** (every feature is implicitly boolean). e.g. `classroom.recording`, `tenancy.custom_domain`, `identity.sso.saml`.
- `LimitKey` value: `limits.` prefix. e.g. `limits.max_users`. `-1` = unlimited, `0` = unavailable.
Expand All @@ -46,7 +46,7 @@ public static readonly LimitKey <Name> = new("limits.<dotted.snake_case>");

### Step 3 — Keep it aligned with LearnStack core

The wire-format string **must** match LearnStack core's `FeatureKeys`/`LimitKeys` registry (`../learnstack/backend/src/LearnStack.SharedKernel/FeatureFlags/`) exactly — LearnStack core reads the key from the projection by string. A mismatch means LearnStack silently never sees the feature. If you add a key Hub authors but LearnStack core doesn't yet read, note the pending LearnStack-side addition (a cross-repo registry-sync follow-up; the durable fix is a shared `LearnStack.Contracts` package, Phase 11 — see [plans.md § Registry sync](../../../docs/modules/plans.md)).
The wire-format string **must** match LearnStack core's `FeatureKeys`/`LimitKeys` registry (`../LearnStack/backend/src/LearnStack.SharedKernel/FeatureFlags/`) exactly — LearnStack core reads the key from the projection by string. A mismatch means LearnStack silently never sees the feature. If you add a key Hub authors but LearnStack core doesn't yet read, note the pending LearnStack-side addition (a cross-repo registry-sync follow-up; the durable fix is a shared `LearnStack.Contracts` package, Phase 11 — see [plans.md § Registry sync](../../../docs/modules/plans.md)).

### Step 4 — Plan validator

Expand Down
2 changes: 1 addition & 1 deletion .claude/skills/add-hub-module/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ description: >

## Purpose

Stand up a new Hub modular-monolith module that complies with the dependency-direction rules from day one: four packages, the right references, a registration extension, a DbContext in the `hub` schema (no RLS), and architecture-test coverage. Mirrors LearnStack's [add-backend-module](../../../../learnstack/.claude/skills/add-backend-module/SKILL.md) minus the tenant-isolation layer.
Stand up a new Hub modular-monolith module that complies with the dependency-direction rules from day one: four packages, the right references, a registration extension, a DbContext in the `hub` schema (no RLS), and architecture-test coverage. Mirrors LearnStack's [add-backend-module](https://github.com/HodeTech/LearnStack/blob/main/.claude/skills/add-backend-module/SKILL.md) minus the tenant-isolation layer.
Comment thread
cemililik marked this conversation as resolved.

## When to use

Expand Down
2 changes: 1 addition & 1 deletion .claude/skills/add-integration-event/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Wire a cross-boundary event the right way: outbox-written in the same transactio
## When not to use

- Intra-module notification → plain MediatR `INotification` (`IDomainEvent`), in-process, same transaction. No outbox.
- A request/response contract → that's one of the four HTTPS endpoints (a fifth needs an ADR in `../learnstack/docs/decisions/`).
- A request/response contract → that's one of the four HTTPS endpoints (a fifth needs an ADR in `../LearnStack/docs/decisions/`).

## Workflow

Expand Down
6 changes: 3 additions & 3 deletions .claude/skills/code-review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@ Walk all five. Cite `file:line` for every finding; classify Blocker / Major / Mi

- Small single-responsibility methods; descriptive names; no dead code / commented-out blocks; no undated TODO.
- No premature abstraction (three similar lines beat a premature helper); no half-finished implementation.
- The change mirrors the LearnStack pattern it's based on (open `../learnstack/backend/src/...` and compare) rather than improvising a parallel shape.
- The change mirrors the LearnStack pattern it's based on (open `../LearnStack/backend/src/...` and compare) rather than improvising a parallel shape.

### 5. Hub-structural (the delta lens)

- Run the full [standards-check](../standards-check/SKILL.md) checklist as the structural backbone: no RLS, `OperatorId` not `UserId`, 6-step pipeline, `hub` schema, no tenant content, no LearnStack-core imports, closed four-endpoint surface.
- Run the full [standards-check](../standards-check/SKILL.md) checklist as the structural backbone: no RLS, `OperatorId` not `UserId`, 6-step pipeline, `hub` schema, no tenant content, no LearnStack-core imports, and the two ADR-0034 contract invariants (Hub stores no tenant content; every crossing goes through a named adapter).
- Architecture tests cover the new structure (`Hub_NeverStores_TenantData` scans the new module; dependency-direction test includes it).
- Adjacent docs updated (module deep dive, glossary, roadmap, ADR).

Expand All @@ -73,7 +73,7 @@ When delegating to a second agent, compose a self-contained prompt that:

- Sets Hub context + **the five Hub deltas** ([../README.md](../README.md)).
- Names the commit / branch / file list under review (`git log --oneline`, `git show --stat`).
- Points at the LearnStack-side authority (`../learnstack/docs/...`) the change derives from.
- Points at the LearnStack-side authority (`../LearnStack/docs/...`) the change derives from.
- Tells the agent to walk all five lenses above.
- Defines the output: verdict + findings as Blocker / Major / Minor / Suggestion with `file:line` + recommendation.
- Insists on reading the surrounding Hub docs (`docs/architecture/`, `docs/modules/`) — don't review in isolation.
Expand Down
12 changes: 6 additions & 6 deletions .claude/skills/commit-and-pr/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ Conventional Commits `type(scope): subject`:
- **Hub scopes:** `hub` (cross-cutting), `hub-domain` (aggregates / modules), `hub-infra` (compose / APISIX / Dapr / Vault / EF), `hub-portal` (operator portal), `hub-docs` (documentation).
- **subject:** imperative, ≤ 72 chars.
- **body:** one short paragraph saying _why_ (the diff is _what_). For a packet, name the packet (`P02c-1`).
- **trailer:** `Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>` (or `Codex …` for Codex sessions). HEREDOC every multi-line message.
- **trailer:** `Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>` (or `Codex …` for Codex sessions). HEREDOC every multi-line message.

```bash
git commit -m "$(cat <<'EOF'
feat(hub-domain): P02c-1 — LearnStackTenant aggregate + DbContext + migration

<why, 1-3 sentences>

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
EOF
)"
```
Expand All @@ -63,18 +63,18 @@ Feature branch `feat/phase-02c-packet-N-<slug>`. Push with `-u` only when the us

### Step 5 — Cross-repo coordination (if the packet spans both repos)

Per [CLAUDE.md § Cross-repo coordination](../../../CLAUDE.md): the Hub-side PR opens first (it carries the canonical contract shape); the LearnStack-side PR references the Hub PR's commit hash; both merge in the same session. Adding/changing a contract endpoint requires a new ADR in `../learnstack/docs/decisions/` first. **Do not** push or merge anything in `../learnstack` without explicit user permission — another agent may be active there.
Per [CLAUDE.md § Cross-repo coordination](../../../CLAUDE.md): the Hub-side PR opens first (it carries the canonical contract shape); the LearnStack-side PR references the Hub PR's commit hash; both merge in the same session. Adding/changing a contract endpoint requires a new ADR in `../LearnStack/docs/decisions/` first. **Do not** push or merge anything in `../LearnStack` without explicit user permission — another agent may be active there.

## Validation

- Commit subject imperative ≤ 72 chars with a valid Hub scope.
- Body explains _why_; AI co-author trailer present.
- Multi-line message via HEREDOC.
- Cross-repo packets: paired-PR plan stated; no unilateral `../learnstack` push.
- Cross-repo packets: paired-PR plan stated; no unilateral `../LearnStack` push.

## Common pitfalls

- **Pushing without being asked.** Default is local commit.
- **Amending / force-pushing `main`.** Forbidden — new commits only.
- **A contract change without an ADR.** The four-endpoint surface is closed; a fifth needs an ADR in `../learnstack/docs/decisions/`.
- **Touching `../learnstack` branch state from a Hub session.** Coordinate; don't interfere with a parallel agent.
- **A contract change without an ADR.** Adding or reshaping an endpoint on the contract surface needs an ADR in `../LearnStack/docs/decisions/` first — it is a cross-repository agreement (ADR-0034).
- **Touching `../LearnStack` branch state from a Hub session.** Coordinate; don't interfere with a parallel agent.
8 changes: 4 additions & 4 deletions .claude/skills/implement-task/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@ The ten steps are mandatory; skipping any is the bug this skill prevents.

### Step 1 — Scope and alignment

Run [start-task](../start-task/SKILL.md): read the right docs in order (Hub docs under `docs/`, then LearnStack authority under `../learnstack/docs/`), confirm phase fit against `docs/roadmap/README.md`, walk the [CLAUDE.md hard rules](../../../CLAUDE.md), and pick the specific workflow skill(s) you'll invoke ([add-hub-module](../add-hub-module/SKILL.md), [add-hub-aggregate](../add-hub-aggregate/SKILL.md), [add-mediatr-handler](../add-mediatr-handler/SKILL.md), [wire-cross-cutting-foundation](../wire-cross-cutting-foundation/SKILL.md), …). Output: a one-paragraph problem statement in your own words, the packet it belongs to, the standards that govern it, the skill(s) you'll use.
Run [start-task](../start-task/SKILL.md): read the right docs in order (Hub docs under `docs/`, then LearnStack authority under `../LearnStack/docs/`), confirm phase fit against `docs/roadmap/README.md`, walk the [CLAUDE.md hard rules](../../../CLAUDE.md), and pick the specific workflow skill(s) you'll invoke ([add-hub-module](../add-hub-module/SKILL.md), [add-hub-aggregate](../add-hub-aggregate/SKILL.md), [add-mediatr-handler](../add-mediatr-handler/SKILL.md), [wire-cross-cutting-foundation](../wire-cross-cutting-foundation/SKILL.md), …). Output: a one-paragraph problem statement in your own words, the packet it belongs to, the standards that govern it, the skill(s) you'll use.

### Step 2 — Inspect and understand

Read every file the change touches **before** editing. Trace one hop out (who calls this, who reads this table, what events flow). Read the relevant Hub design spec (`docs/architecture/*.md`, `docs/modules/*.md`) and the LearnStack-side ADR/standard it derives from. If `git log` shows recent edits, read the commit messages for direction. **Mirror, don't invent:** if a pattern exists in `../learnstack/backend/src/`, open it and reproduce it (adjusting for the Hub deltas), rather than improvising.
Read every file the change touches **before** editing. Trace one hop out (who calls this, who reads this table, what events flow). Read the relevant Hub design spec (`docs/architecture/*.md`, `docs/modules/*.md`) and the LearnStack-side ADR/standard it derives from. If `git log` shows recent edits, read the commit messages for direction. **Mirror, don't invent:** if a pattern exists in `../LearnStack/backend/src/`, open it and reproduce it (adjusting for the Hub deltas), rather than improvising.

### Step 3 — Plan

State the plan briefly: (1) what you'll do in 1-3 sentences; (2) which files/dirs (paths only); (3) which validation you'll run; (4) any assumption that, if wrong, invalidates the plan. Ask for confirmation **only** when the plan touches: more than one module's `Domain`; an Accepted ADR (either repo); the Hub HTTPS contract surface; a destructive migration; or anything in `../learnstack`. For routine Hub work, state the plan and continue.
State the plan briefly: (1) what you'll do in 1-3 sentences; (2) which files/dirs (paths only); (3) which validation you'll run; (4) any assumption that, if wrong, invalidates the plan. Ask for confirmation **only** when the plan touches: more than one module's `Domain`; an Accepted ADR (either repo); the Hub HTTPS contract surface; a destructive migration; or anything in `../LearnStack`. For routine Hub work, state the plan and continue.

### Step 4 — Implement

Expand Down Expand Up @@ -99,5 +99,5 @@ Compose the review prompt per [code-review § review-agent prompt](../code-revie
- **Rushing Step 2.** The next eight steps cost an order of magnitude more when inspect is sloppy.
- **Forgetting the Hub deltas.** Copying a LearnStack pattern verbatim drags in RLS / `UserId` / `TenantContextBehavior` that Hub must not have. Adjust as you mirror.
- **Skipping the dotnet PATH fix.** `dotnet` is .NET 9; use `~/.dotnet/dotnet`. #1 time-sink.
- **Touching `../learnstack` without coordination.** Hub-side packets are Hub-only; LearnStack-side work is a separate coordinated packet.
- **Touching `../LearnStack` without coordination.** Hub-side packets are Hub-only; LearnStack-side work is a separate coordinated packet.
- **Stale docs / dropped Turkish summary / missing review prompt.** All three are part of "done."
Loading
Loading