

---
name: platform-feature-finish
description: Commit, push, create a Gitea PR from a TenantPilot platform feature branch into platform-dev, and optionally refresh the platform-dev to dev integration PR by rebase.
---

# Skill: platform-feature-finish

## Purpose

Automate the TenantPilot platform feature completion workflow.

Trigger this skill when the user says something like:

- "alles committen pushen und PR gegen platform-dev"
- "feature fertig, bitte PR erstellen"
- "platform feature abschließen"
- "commit push PR mit Gitea MCP"
- "mach PR gegen platform-dev"
- "finish platform feature"
- "platform-dev nach dev vorbereiten"
- "platform-dev PR aktualisieren"
- "out-of-date mit dev beheben"
- "integration PR refresh"
- "platform-dev auf dev rebasen"

This skill handles:

1. Validate current Git branch
2. Commit all feature changes
3. Push current feature branch
4. Create a Gitea pull request into `platform-dev`
5. Refresh the `platform-dev` → `dev` integration PR when explicitly requested
6. Report the PR link and next integration step

---

## Branch Model

TenantPilot uses area branches:

```text
dev           = shared integration branch
platform-dev  = platform/application area integration branch
website-dev   = website/marketing area integration branch
```

For platform features:

```text
platform-dev
  ↓
feature branch
  ↓
PR back to platform-dev
  ↓
platform-dev → dev integration PR
```

Rules:

- Platform feature branches MUST target `platform-dev`.
- Do NOT target `dev` directly unless the user explicitly asks.
- Do NOT use `website-dev` for platform features.
- `platform-dev` is the default PR base for TenantPilot platform/application work.
- `dev` is the shared integration branch.

### Solo Workflow Rule

The user works alone on `platform-dev`.

For refreshing the integration branch before opening or updating the PR `platform-dev` → `dev`, prefer rebase over merge.

Do not repeatedly merge `origin/dev` into `platform-dev` for refresh.

Avoid creating repeated merge commits like:

```text
Merge remote-tracking branch 'origin/dev' into platform-dev
```

Use `--force-with-lease`, never plain `--force`.

If rebase conflicts occur, stop and report the conflict files.

---

## Preconditions

Before committing:

1. Confirm repository root.
2. Confirm current branch is not protected.

Protected branches:

```text
dev
platform-dev
website-dev
main
master
```

If the current branch is protected, STOP and report:

```text
Ich bin auf einem geschützten Branch. Bitte zuerst einen Feature-Branch auschecken.
```

3. Confirm remote exists.
4. Confirm there are local changes, untracked files, or unpushed commits.
5. Confirm there are no unresolved conflicts.

Do not ask for confirmation unless:

- The current branch is protected.
- Git status indicates unresolved conflicts.
- There is no remote configured.
- `.env` or other local secret/config files would be committed.
- Commit fails.
- Push fails.
- Gitea MCP PR creation fails.

---

## Required Tools

Use terminal for Git operations.

Use Gitea MCP for pull request creation.

Preferred Gitea MCP operation:

```text
create_pull_request
```

Required PR parameters:

```json
{
  "owner": "ahmido",
  "repo": "TenantAtlas",
  "head": "<current-feature-branch>",
  "base": "platform-dev",
  "title": "<generated-title>",
  "body": "<generated-body>"
}
```

---

## Workflow

### Step 1 — Inspect Git state

Run:

```bash
git rev-parse --show-toplevel
git rev-parse --abbrev-ref HEAD
git status --porcelain
git status -sb
git config --get remote.origin.url
git log --oneline --max-count=5
```

Determine:

- repository root
- current branch
- changed files
- untracked files
- remote URL
- whether there are unpushed commits
- whether unresolved conflicts exist

If the current branch is protected, stop.

If unresolved conflicts exist, stop.

If no remote exists, stop.

---

### Step 2 — Check for local environment files

Before `git add -A`, check whether local environment/config files are modified or untracked:

```bash
git status --porcelain | grep -E '(^.. \.env$|^.. apps/platform/\.env$|^.. .*\.env$)' || true
```

If `.env` or another environment file is included, STOP and report:

```text
Achtung: Eine .env-/Environment-Datei ist geändert oder untracked. Ich committe das nicht automatisch. Bitte prüfen oder aus dem Commit entfernen.
```

Do not commit secrets or local runtime configuration.

---

### Step 3 — Build commit message

Use the current branch name.

If branch starts with a spec number, for example:

```text
256-external-support-desk-handoff
```

Generate:

```text
feat(specs/256): external support desk handoff
```

If branch does not contain a spec number, generate:

```text
feat(platform): complete <branch-name>
```

Rules:

- Use lowercase subject.
- Use feature-style subject.
- Do not include `WIP`.
- Do not include `final`.
- Do not include overly generic `updates`.

Examples:

```text
feat(specs/256): external support desk handoff
feat(specs/252): platform localization v1
feat(platform): improve tenant review workspace
```

---

### Step 4 — Commit all changes

Run:

```bash
git add -A
git commit -m "<commit-message>"
```

If there are no local changes to commit, continue only if the branch has unpushed commits.

Check unpushed commits with:

```bash
git status -sb
git log --oneline origin/<current-branch>..HEAD
```

If there are no local changes and no unpushed commits, report:

```text
Es gibt keine lokalen Änderungen und keine unpushed commits. Ich erstelle keinen leeren Commit.
```

Then continue to PR creation only if the branch already exists remotely or can be pushed.

---

### Step 5 — Push branch

Run:

```bash
git push --set-upstream origin <current-branch>
```

If the upstream already exists, this is acceptable.

Never force-push unless the user explicitly requests it.

---

### Step 6 — Create PR into platform-dev via Gitea MCP

Use Gitea MCP to create a pull request:

```json
{
  "owner": "ahmido",
  "repo": "TenantAtlas",
  "head": "<current-feature-branch>",
  "base": "platform-dev",
  "title": "<commit-message>",
  "body": "Implements platform feature branch `<current-feature-branch>`.\n\nTarget branch: `platform-dev`.\n\nFollow-up integration path after merge:\n\n`platform-dev` → `dev`."
}
```

If a PR already exists for the same branch and base, do not create a duplicate.

Report the existing PR if available.

---

## Optional Step — Check platform-dev to dev PR

After creating the feature PR, check whether an open integration PR exists:

```text
platform-dev → dev
```

If a Gitea MCP list/search pull request function is available, use it.

If one exists, report:

```text
Der Folge-PR `platform-dev` → `dev` existiert bereits: <url>
```

If none exists, report:

```text
Nach dem Merge dieses Feature-PRs sollte der Integrations-PR `platform-dev` → `dev` erstellt oder aktualisiert werden.
```

Do not automatically create the `platform-dev` → `dev` PR unless the user explicitly asks for it.

Reason: before the feature PR is merged into `platform-dev`, the integration PR may not include the new feature yet.

---

## Integration Refresh Mode

Use this mode when the user explicitly says one of the following:

- "platform-dev nach dev vorbereiten"
- "platform-dev PR aktualisieren"
- "out-of-date mit dev beheben"
- "integration PR refresh"
- "platform-dev auf dev rebasen"
- "auch platform-dev nach dev"
- "und danach platform-dev nach dev"
- "full integration"
- "kompletten platform-dev zu dev PR machen"
- "folge-pr erstellen"

This mode prepares or updates the integration PR:

```text
platform-dev → dev
```

Because the user works alone on `platform-dev`, prefer rebase over merge.

### Integration Refresh Preconditions

Before running this mode:

1. Ensure the working tree is clean.
2. Ensure there are no unresolved conflicts.
3. Fetch remote branches.
4. Ensure `origin/platform-dev` exists.
5. Ensure `origin/dev` exists.

If the working tree is dirty, STOP and report:

```text
Der Working Tree ist nicht sauber. Bitte erst Änderungen committen, stashen oder verwerfen, bevor `platform-dev` auf `dev` rebased wird.
```

If unresolved conflicts exist, STOP and report the conflict files.

### Integration Refresh Workflow

Run:

```bash
git fetch origin
git checkout platform-dev
git reset --hard origin/platform-dev
git rebase origin/dev
git push --force-with-lease origin platform-dev
```

After pushing, verify that `origin/dev` is now an ancestor of `origin/platform-dev`:

```bash
git fetch origin
git merge-base --is-ancestor origin/dev origin/platform-dev \
  && echo "OK: platform-dev contains dev" \
  || echo "OUTDATED: platform-dev does not contain dev"
```

If the verification prints `OUTDATED`, stop and report it. Do not claim the PR is up-to-date.

Rules:

- Do not merge `origin/dev` into `platform-dev` for this refresh.
- Do not create repeated merge commits from `origin/dev` into `platform-dev`.
- Use `git push --force-with-lease origin platform-dev` after a successful rebase.
- Never use plain `git push --force`.
- If `git rebase origin/dev` reports conflicts, stop immediately.
- Do not continue to PR creation while a rebase is unresolved.
- Do not auto-merge the PR.
- Do not claim Gitea will remove the out-of-date warning unless the ancestor check succeeds.

If rebase conflicts occur, report:

```text
Rebase-Konflikte erkannt. Ich habe gestoppt.

Konfliktdateien:
<files>

Bitte Konflikte lösen, dann `git rebase --continue` ausführen oder den Rebase mit `git rebase --abort` abbrechen.
```

### Create or Report Integration PR

After the rebase, push, and ancestor verification succeeded, use Gitea MCP to create or report the integration PR:

```json
{
  "owner": "ahmido",
  "repo": "TenantAtlas",
  "head": "platform-dev",
  "base": "dev",
  "title": "chore(platform): merge platform-dev into dev",
  "body": "Integrates latest TenantPilot platform changes from `platform-dev` into `dev`.\n\nThis PR was created by agent on user request; do not merge automatically."
}
```

If an open PR already exists for `platform-dev` → `dev`, do not create a duplicate. Report the existing PR.

### Integration Refresh Reporting Format

Final response for this mode must include:

```text
Fertig.

- Branch aktualisiert: platform-dev
- Refresh-Methode: rebase auf origin/dev
- Ancestor-Check: origin/dev ist Ancestor von origin/platform-dev
- Push: --force-with-lease origin/platform-dev
- Integration PR: <url>
- Base: dev
- Hinweis: PR wurde nicht automatisch gemerged.
```

Do not claim tests passed unless they were actually executed.

---

## Reporting Format

Final response must be concise and include:

```text
Fertig.

- Branch: <branch>
- Commit: <commit-sha or "keine neuen Änderungen">
- Push: origin/<branch>
- PR: <url>
- Base: platform-dev
- Nächster Schritt: Nach Merge `platform-dev` → `dev` PR aktualisieren/erstellen
```

If tests were not run, say:

```text
Tests wurden in diesem Skill nicht automatisch ausgeführt.
```

Do not claim tests passed unless the tool actually ran them.

---

## Safety Rules

- Never commit directly to `dev`, `platform-dev`, `website-dev`, `main`, or `master`.
- Never force-push unless explicitly requested.
- For Integration Refresh Mode only, `git push --force-with-lease origin platform-dev` is allowed because the user works alone on `platform-dev`; never use plain `--force`.
- Never auto-merge PRs unless explicitly requested.
- Never target `dev` directly for platform feature PRs unless explicitly requested.
- Never delete branches unless explicitly requested.
- Never claim tests were run unless the tool actually ran them.
- Never commit `.env`, secrets, local tokens, local mock-server configuration, or temporary runtime-only changes.
- If migrations were created, mention that the target environment needs migration execution after deployment.
- If unresolved conflicts exist, stop.

---

## Useful Commands

Inspect:

```bash
git rev-parse --show-toplevel
git rev-parse --abbrev-ref HEAD
git status --porcelain
git status -sb
git config --get remote.origin.url
```

Detect protected branch:

```bash
branch="$(git rev-parse --abbrev-ref HEAD)"
case "$branch" in
  dev|platform-dev|website-dev|main|master)
    echo "PROTECTED_BRANCH:$branch"
    exit 2
    ;;
esac
```

Detect unresolved conflicts:

```bash
git diff --name-only --diff-filter=U
```

Detect `.env` changes:

```bash
git status --porcelain | grep -E '(^.. \.env$|^.. apps/platform/\.env$|^.. .*\.env$)' || true
```

Commit:

```bash
git add -A
git commit -m "<message>"
```

Push:

```bash
git push --set-upstream origin "$(git rev-parse --abbrev-ref HEAD)"
```

Latest commit:

```bash
git rev-parse --short HEAD
git log -1 --pretty=%s
```

Integration refresh:

```bash
git fetch origin
git checkout platform-dev
git reset --hard origin/platform-dev
git rebase origin/dev
git push --force-with-lease origin platform-dev
```

Verify integration refresh:

```bash
git fetch origin
git merge-base --is-ancestor origin/dev origin/platform-dev \
  && echo "OK: platform-dev contains dev" \
  || echo "OUTDATED: platform-dev does not contain dev"
```

Check rebase conflicts:

```bash
git diff --name-only --diff-filter=U
```

---

## Example User Request

User:

```text
alles committen pushen und pr gegen platform-dev mit gitea mcp
```

Assistant should:

1. Check current branch.
2. Stop if branch is protected.
3. Stop if `.env` or secrets would be committed.
4. Commit all changes.
5. Push current branch.
6. Create PR into `platform-dev` with Gitea MCP.
7. Report result.

Do not ask unnecessary follow-up questions.

---

## Example Integration Refresh Request

User:

```text
platform-dev PR aktualisieren
```

Assistant should:

1. Ensure the working tree is clean.
2. Fetch origin.
3. Checkout `platform-dev`.
4. Reset local `platform-dev` to `origin/platform-dev`.
5. Rebase `platform-dev` onto `origin/dev`.
6. Push with `--force-with-lease`.
7. Verify `origin/dev` is an ancestor of `origin/platform-dev`.
8. Create or report the PR `platform-dev` → `dev`.
9. Report result.

Do not merge the PR automatically.