Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f34183d
Add Puber release control plane
rovkinmax Aug 24, 2026
1867484
Correct Puber release control plane
rovkinmax Aug 24, 2026
becc765
Fix Puber release source closure
rovkinmax Aug 24, 2026
8aef6b2
fix: harden puber release runtime contracts
rovkinmax Aug 25, 2026
ff09447
chore: bind final release sources
rovkinmax Aug 25, 2026
f4a3186
fix: validate normalized release sources
rovkinmax Aug 25, 2026
08b67e5
fix: bind GitHub observation authority
rovkinmax Aug 25, 2026
54ed939
fix: close puber release publication carriers
rovkinmax Aug 25, 2026
88a5620
test: keep release fixture commit idempotent
rovkinmax Aug 25, 2026
315a6ba
fix: attest release observation and cleanup authority
rovkinmax Aug 25, 2026
7deb950
Harden release cleanup evidence contract
rovkinmax Aug 25, 2026
30a3463
Correct release cleanup lifecycle and adversarial coverage
rovkinmax Aug 25, 2026
ea80935
Bind cleanup identity and normalize repeated Janitor retries
rovkinmax Aug 25, 2026
5bb57db
Correct release cleanup evidence boundaries
rovkinmax Aug 25, 2026
332957d
Close final release runtime boundaries
rovkinmax Aug 25, 2026
13faad6
Close final release carrier and retention checks
rovkinmax Aug 25, 2026
c91041b
Finalize release cleanup bytecode and mode checks
rovkinmax Aug 25, 2026
c796f16
Fix main actions and paging item identity
rovkinmax Aug 25, 2026
ff29aff
Harden S10 regression test determinism
rovkinmax Aug 25, 2026
1ddd15f
Baseline inherited Detekt findings
rovkinmax Aug 25, 2026
c0b5ede
Fix integration with current master
rovkinmax Aug 31, 2026
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
78 changes: 29 additions & 49 deletions .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,75 +4,55 @@ on:
pull_request:
branches: [ master ]

permissions:
contents: read

concurrency:
group: pr-${{ github.event.pull_request.number }}
cancel-in-progress: true

jobs:
detekt:
name: Detekt
if: false
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
java-version: '17'
distribution: 'temurin'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5

- run: chmod +x gradlew

- name: Run Detekt
run: ./gradlew detektAll
persist-credentials: false
- uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00
with:
java-version: '21'
distribution: temurin
- name: Assert GitHub-hosted runner
run: test "${RUNNER_ENVIRONMENT:-github-hosted}" = github-hosted
- run: ./gradlew :app:detektAll

unit-tests:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
java-version: '17'
distribution: 'temurin'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5

- run: chmod +x gradlew

- name: Run unit tests
run: ./gradlew testProdDebugUnitTest

- name: Upload test results
if: failure()
uses: actions/upload-artifact@v4
persist-credentials: false
- uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00
with:
name: test-results
path: app/build/reports/tests/
java-version: '21'
distribution: temurin
- name: Assert GitHub-hosted runner
run: test "${RUNNER_ENVIRONMENT:-github-hosted}" = github-hosted
- run: ./gradlew :app:testProdDebugUnitTest

build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
java-version: '17'
distribution: 'temurin'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5

- run: chmod +x gradlew

- name: Build debug APK
run: ./gradlew assembleProdDebug
persist-credentials: false
- uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00
with:
java-version: '21'
distribution: temurin
- name: Assert GitHub-hosted runner
run: test "${RUNNER_ENVIRONMENT:-github-hosted}" = github-hosted
- run: ./gradlew :app:assembleProdDebug
120 changes: 19 additions & 101 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,121 +4,39 @@ on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
release_tag:
description: 'Release tag to publish, for example v1.2.0'
required: true
type: string

permissions:
contents: write

jobs:
test:
name: Unit Tests
runs-on: ubuntu-latest
env:
RELEASE_REF: ${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.ref }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ env.RELEASE_REF }}

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5

- run: chmod +x gradlew

- name: Run unit tests
run: ./gradlew testProdDebugUnitTest

release:
name: Build & Publish
needs: test
runs-on: ubuntu-latest
env:
RELEASE_REF: ${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.ref }}
RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.ref_name }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
ref: ${{ env.RELEASE_REF }}

- name: Set up JDK 17
uses: actions/setup-java@v4
persist-credentials: false
ref: ${{ github.ref }}
- uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00
with:
java-version: '17'
distribution: 'temurin'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5

- run: chmod +x gradlew

- name: Validate release secrets
env:
RELEASE_KEYSTORE_BASE64: ${{ secrets.RELEASE_KEYSTORE_BASE64 }}
STOREPASS: ${{ secrets.STOREPASS }}
KEYALIAS: ${{ secrets.KEYALIAS }}
PUBER_CLIENT_SECRET: ${{ secrets.PUBER_CLIENT_SECRET }}
TMDB_READ_ACCESS_TOKEN: ${{ secrets.TMDB_READ_ACCESS_TOKEN }}
run: |
missing=()
for name in RELEASE_KEYSTORE_BASE64 STOREPASS KEYALIAS PUBER_CLIENT_SECRET TMDB_READ_ACCESS_TOKEN; do
if [[ -z "${!name}" ]]; then
missing+=("$name")
fi
done

if (( ${#missing[@]} > 0 )); then
printf 'Missing required GitHub Secrets:\n' >&2
printf ' - %s\n' "${missing[@]}" >&2
exit 1
fi

- name: Build release APK
env:
RELEASE_KEYSTORE_BASE64: ${{ secrets.RELEASE_KEYSTORE_BASE64 }}
STOREPASS: ${{ secrets.STOREPASS }}
KEYALIAS: ${{ secrets.KEYALIAS }}
KEYPASS: ${{ secrets.KEYPASS }}
PUBER_CLIENT_SECRET: ${{ secrets.PUBER_CLIENT_SECRET }}
TMDB_READ_ACCESS_TOKEN: ${{ secrets.TMDB_READ_ACCESS_TOKEN }}
run: ./gradlew assembleProdRelease

- name: Prepare release artifacts
java-version: '21'
distribution: temurin
- name: Assert GitHub-hosted runner
run: test "${RUNNER_ENVIRONMENT:-github-hosted}" = github-hosted
- run: ./gradlew :app:assembleProdRelease
- name: Prepare release artifacts and checksum
run: |
mkdir -p release-artifacts
apk_path="$(find app/build/outputs/apk/prod/release -maxdepth 1 -type f -name '*.apk' | head -n 1)"
if [[ -z "$apk_path" ]]; then
echo "Release APK was not produced" >&2
exit 1
fi

cp "$apk_path" "release-artifacts/puber-${RELEASE_TAG}.apk"
(
cd release-artifacts
shasum -a 256 "puber-${RELEASE_TAG}.apk" > "puber-${RELEASE_TAG}.apk.sha256"
)

- name: Upload APK artifact
uses: actions/upload-artifact@v4
test -n "$apk_path"
cp "$apk_path" "release-artifacts/puber-${GITHUB_REF_NAME}.apk"
(cd release-artifacts && sha256sum "puber-${GITHUB_REF_NAME}.apk" > "puber-${GITHUB_REF_NAME}.apk.sha256")
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: puber-${{ env.RELEASE_TAG }}
name: puber-${{ github.ref_name }}
path: release-artifacts/*
if-no-files-found: error

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ env.RELEASE_TAG }}
name: Puber ${{ env.RELEASE_TAG }}
generate_release_notes: true
files: release-artifacts/*
- name: Create GitHub Release with empty initial body
env:
GH_TOKEN: ${{ github.token }}
run: gh release create "$GITHUB_REF_NAME" --verify-tag --title "Puber $GITHUB_REF_NAME" --notes "" --generate-notes=false release-artifacts/*
47 changes: 5 additions & 42 deletions .kent/commands/cleanup-task.md
Original file line number Diff line number Diff line change
@@ -1,47 +1,10 @@
---
description: Conservative Kent task cleanup report
description: Conservative Puber task cleanup report
---

# Cleanup Task

Produces a conservative cleanup report for completed Kent workflow tasks.

## Usage

```
/prompt:cleanup-task
/prompt:cleanup-task <task-short-id>
```

## Policy

The Cleanup agent is report-first and never removes its own Kent-managed
worktree. The generated Task Janitor runs after this session exits and owns
deterministic deletion.

## What It Does

1. Determine the primary checkout:
```bash
git worktree list --porcelain
```
2. Inspect only the current task workspace and branch.
3. Report clean/dirty state, authoritative merged/no-PR proof, remote branch
state, and any unique content.
4. Do not invoke `git worktree remove` or `kent worktree delete` for the managed
task worktree.
5. Poll and close every task-owned background shell or kept-open tool session.
6. Run `kent worktree leave`; the Janitor will verify this session no longer
targets the task worktree.
7. Emit the complete `run_janitor` contract required by the workflow prompt.

## Output

Return a short human-readable `cleanup_report`:

```markdown
Cleanup report:
- Preflight: exact task worktree and merged PR verified
- Preserved: none
- Handoff: Task Janitor may remove the clean managed worktree and task branch
```
Inspect only the exact task worktree, branch, PR proof, and runtime carrier.
Report first. Preserve dirty, unpushed, unmerged, or unclear resources. The
schema-4 Janitor may delete only resources conclusively safe for the selected
cleanup mode; it never touches the primary checkout or live Kent state.
75 changes: 6 additions & 69 deletions .kent/commands/compliance-review.md
Original file line number Diff line number Diff line change
@@ -1,74 +1,11 @@
---
description: Read-only compliance review for workflow outputs
description: Read-only compliance review for Puber release outputs
---

# Compliance Review

Run this only from a Kent workflow compliance node assigned to `compliance_reviewer`.

## Purpose

Review the plan and work product only for compliance with authoritative project rules, AGENTS.md, specs, user-approved
design choices, task body, and workflow contract. This is not general code review, architecture review, QA, or cleanup.

## Authority Hierarchy

Use this hierarchy, descending:

1. The plan's Design section, when it clearly records user decisions.
2. The task body and human-authored task comments.
3. AGENTS.md rules. Treat changes to AGENTS.md in the worktree as unauthorized unless the task explicitly asked for them.
4. Spec files and project-local contracts. Treat changes to specs/contracts as unauthorized unless clearly based on #1 or #2.

Agent-authored comments, implementation commentary, and previous review summaries are useful context, but not authority.

## Required Inputs

The workflow prompt must provide the available inputs:

- `workspace_path`: the `.todo/<task>` workspace or task workspace being reviewed, when one exists.
- `review_context`: for generated Delivery workflows, the canonical aggregate
containing plan/spec paths, reviewed scope, changed files, verification and
review reports, Gate decision, and Smoke evidence or bypass rationale.
- `plan_path` or `plan_file_path`: the authoritative plan, when one exists.
- `reviewed_scope`: what work product to inspect.
- `commentary`: implementation/review/verification summary from the previous node.
- `changed_files`: changed files, when known.

When `review_context` contains these inputs, do not require duplicate standalone
fields.

If a required source is missing, report the review as waiting for user action or incomplete and name the missing source.

## Work Mode

1. Read applicable AGENTS.md files first.
2. Read the plan/spec/contract sources named in the workflow prompt.
3. Inspect the reviewed scope and nearby files only as needed to verify compliance.
4. Treat the work as non-compliant by default until you verify it against the rules.
5. Report only direct compliance violations, spec mismatches, unauthorized rule/spec changes, missing required updates, or
ambiguity where a rule cannot be applied safely.
6. Do not edit files, apply patches, commit, mutate caches, or run state-changing commands.

## Completion Contract

Complete with:

- The success transition named in the current workflow prompt when no compliance violations are found. New PR-producing
workflows use `ship_pr`; legacy no-PR release workflows may use `cleanup`. Provide `compliance_report`.
- `needs_changes` when compliance violations require a fix/rework pass. Generated
Delivery workflows provide `workspace_path` and `fix_context`; follow the
current workflow prompt for legacy contracts.
- `needs_user_action` when required rule/spec/task sources are missing or
contradictory. Generated Delivery workflows provide `workspace_path`,
`review_context`, and `blocker_reason`.

Do not hardcode `done` from this command; `done` is reserved for cleanup completion.

For every finding include:

- Violated source and rule.
- Exact reviewed location.
- Observed non-compliant behavior.
- Why it violates the cited rule.
- Minimum compliance requirement needed to resolve it.
Review the exact S05 allowlist, schema-4 graph identity, deterministic runtime
carriers, Java-21 pinned PR checks, and no-effect boundaries. Do not edit,
commit, push, merge, tag, publish, dispatch, rerun, or mutate Kent state.
Release publication is a separate approval-gated operation and is never part
of PR Checks.
Loading
Loading