Skip to content

feat: add the feature factory, share one email domain and drop the quickstart certificate - #6

Merged
kora-agent merged 5 commits into
mainfrom
feat/feature-factory
Oct 30, 2026
Merged

kora-agent merged 5 commits into
mainfrom
feat/feature-factory

Conversation

@justinwilkin

@justinwilkin justinwilkin commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

Adds factories/feature, a factory that turns a feature request into an approved spec and builds it task by task. Moves the examples to kora 0.11.3, puts every tenant on one email domain with claim binding, and serves the quickstart over plain HTTP with no certificate.

Changes

  • factories/feature: The platform repository (tenant feature, models) and the factory repository (GitHub connection and source, build environment, maintainer role, five agents, eight triggers).
    • spec-writer turns an issue labelled ready-to-spec into a spec pull request on spec/<issue>.
    • A person approves the spec by merging it. captain then splits it into tasks and starts an implementer run for each through the kora MCP server's runs:start tool.
    • The captain's scopes let it start and read implementer runs only. It keeps its checklist on the issue, and a merged task or a needs-human label wakes it.
    • reviewer reviews each task pull request. verifier checks it against the spec once CI passes. Reviews, verifications and failed CI route back to the implementer that owns the task.
  • kora 0.11.3: versions.mk installs 0.11.3. 0.11.1 keeps the console's session cookie working in Safari on a localhost origin over HTTP. 0.11.2 holds an agent update until every agent its scopes name exists.
  • One email domain: Every example tenant claims local.runkora.io and binds to one tenant-<name> group with claimBinding. Each quickstart user signs in as <tenant>-<role>@local.runkora.io and belongs to one tenant group. The single-tenant users keep admin@ and engineer@.
  • No certificate: The console is http://kora.localhost:9880 and Dex is http://dex.localhost:5557/dex. Browsers treat *.localhost as a secure origin, so make up no longer runs mkcert or installs a CA. make tunnel and make alert use the HTTP addresses.
  • Quickstart: make example offers the feature factory. The READMEs and the Users list use the new sign-in emails.

Testing

  • All twelve kustomizations build.
  • On the quickstart with kora 0.11.1:
    • All six tenants claim local.runkora.io with a binding and reach Ready. The identity service loads them with no overlap error.
    • Each tenant group in glauth holds exactly its two users.
    • admin@local.runkora.io signed in to the example tenant over http://kora.localhost:9880 in Chrome and Safari.
  • Ran the feature factory against a private repository:
    • spec-writer opened a spec with four ordered tasks and acceptance criteria.
    • After the spec merged, captain found the implementer with agents:list and started its first task with runs:start. kora recorded the captain as the run's creator.
    • implementer opened the task pull request. The reviewer and verifier runs started from it.
  • The captain's first run did not see the implementer. Its grant had dropped the agents:*:implementer:* scopes, because the implementer was still provisioning when the grant was written. kora 0.11.2 fixes this (fix(agents): fail a declared agent update when its grant is refused kora#857).

A spec writer turns a labelled issue into a spec pull request. When a person
merges it, the captain splits the spec into tasks and starts an implementer
run for each through the kora MCP server. Its scopes let it start and read
implementer runs only. Reviews, verifications and failed CI route back to the
implementer that owns each task.
Every example tenant claims local.runkora.io and binds to a tenant group in
the groups claim with claimBinding, which 0.11.0 ships. Each quickstart user
signs in as <tenant>-<role>@local.runkora.io and belongs to one tenant group.
@runkora

runkora Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Visual Walkthrough

This pull request adds the feature factory and serves the quickstart over plain HTTP on localhost.

Spec to task start

An approved spec merge starts the captain, which starts one implementer run per task.

sequenceDiagram
    participant G as GitHub
    participant T as Triggers
    participant S as Spec writer
    participant C as Captain
    participant I as Implementer
    G->>T: issue labelled ready-to-spec
    T->>S: start spec run
    S-->>G: open spec pull request
    G->>T: spec pull request merged
    T->>C: start planning run
    C-->>G: post task checklist
    loop each task with no open dependency
        C->>I: start implementer run
        I-->>G: open task pull request
    end
    alt run ended before pull request opened
        C->>I: start replacement run
    end
    G->>T: task pull request merged
    T->>C: start next tasks
Loading
Node Code Symbols
Triggers spec-on-ready.yaml spec-on-ready, plan-on-spec-merged, next-on-task-merged
Spec writer spec-writer.yaml spec-writer
Captain captain.yaml captain
Implementer implementer.yaml implementer
Review and verification loop

Each task pull request gets a review and a verification, and failing CI or review returns to the implementer.

sequenceDiagram
    participant G as GitHub
    participant T as Triggers
    participant R as Reviewer
    participant V as Verifier
    participant I as Implementer
    participant C as Captain
    G->>T: pull request opened or synchronized
    T->>R: start review run
    R-->>G: review as comment
    G->>T: CI run completes
    alt CI passed
        T->>V: start verification run
        V-->>G: verification as comment
    else CI failed
        T->>I: start fix run
    end
    G->>T: review submitted
    T->>I: address review
    I-->>G: push fixes to branch
    alt still failing after third push
        I-->>G: add needs-human label
        G->>T: needs-human label added
        T->>C: start captain run
        C-->>G: mark task blocked
    end
Loading
Node Code Symbols
Triggers review-task-pr.yaml review-task-pr, verify-on-ci-pass, implementer-on-ci
Reviewer reviewer.yaml reviewer
Verifier verifier.yaml verifier
Implementer implementer.yaml implementer
Captain captain.yaml captain
Sign-in and quickstart routes

Tenants and identity reach Dex over plain HTTP on dex.localhost, and the gateway no longer uses TLS.

flowchart TB
    BR[Browser]:::context
    subgraph quick [Quickstart cluster]
        GW[k3d gateway on port 9880]:::changed
        CON[Console at kora.localhost]:::changed
        DEX[Dex at dex.localhost]:::changed
        HA[Identity host alias]:::changed
        ID[Identity service]:::context
        TEN[Tenant issuerURL]:::changed
        TLS[mkcert TLS certificate]:::removed
    end
    BR -->|plain HTTP| GW
    GW -->|routes to console| CON
    BR -->|sign in| DEX
    TEN -->|trusts issuer| ID
    ID -->|resolves dex.localhost| HA
    HA -->|reaches Dex| DEX
    TLS -->|no longer terminates TLS| GW
    classDef added fill:#1f883d,stroke:#1a7f37,stroke-width:2px,color:#ffffff
    classDef changed fill:#bf8700,stroke:#9a6700,stroke-width:2px,color:#ffffff
    classDef removed fill:#cf222e,stroke:#a40e26,stroke-width:2px,stroke-dasharray:5,color:#ffffff
    classDef context fill:transparent,stroke:#8c959f,stroke-width:1px,stroke-dasharray:3,color:#8c959f
    linkStyle default stroke:#8c959f,stroke-width:2px
    style quick fill:transparent,stroke:#8c959f
Loading

Legend: green = added, amber = changed, red = removed, dashed grey = context

Node Code Symbols
k3d gateway on port 9880 k3d.yaml ports, 9880:80
Console at kora.localhost kora.yaml frontendHost, frontend.config.nextPublicAppUrl
Dex at dex.localhost dex.yaml config.yaml, Service dex
Identity host alias kora.yaml identity.hostAliases
Tenant issuerURL example.yaml issuerURL
mkcert TLS certificate Makefile $(SECRETS)/tls.crt

@runkora runkora Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Walkthrough

Adds a feature factory (spec, plan, implement, review, verify agents with triggers) and moves the example tenants to one shared local.runkora.io email domain with per-tenant Dex groups.

Severity Finding Location
medium Add a sender restriction to the review trigger factories/feature/factory/triggers/implementer-on-review.yaml:15

Review effort: High
Risk: Medium, new factory and sign-in identity changes
Coverage: 43 of 43 files reviewed

Where to focus

Area Why it needs a person
factories/feature/factory/triggers Decide which review authors may drive a write-enabled agent.
quickstart/manifests/dex/glauth.yaml Verify the group-per-tenant bindings match every tenant manifest.
factories/feature/factory/agents Check the agent actions cover the labels and comments the prompts request.

Lower risk

Area Why
factories/feature/platform/models Model manifests copied from sibling factories.
READMEs Text updates for the shared email domain.
Changes by area
Area Files Change
factories/feature 28 New feature factory and platform tenant
quickstart 4 Dex users and groups, Makefile, docs
tenants and READMEs 9 Shared email domain and claim bindings
Makefile, versions.mk 2 Register feature factory, version bump
Checked

Manifest cross-references, kustomization resource lists, Makefile secret names, Dex group bindings.

The console is http://kora.localhost:9880 and Dex is
http://dex.localhost:5557/dex. Browsers treat *.localhost as a secure origin,
so the quickstart needs no certificate and installs no CA. kora 0.11.1 keeps
the session cookie working in Safari on that origin.
@justinwilkin justinwilkin changed the title feat: add the feature factory and share one email domain across tenants feat: add the feature factory, share one email domain and drop the quickstart certificate Oct 29, 2026
@kora-agent
kora-agent merged commit fb3736c into main Oct 30, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants