Skip to content
sindukePublic

About

No description, website, or topics provided.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Repository files navigation

Daylily

Modern AI-first Swift web framework

Built for the Swift Concurrency era.
Designed for humans and AI agents together.

English | 简体中文

Documentation • Quick Start • Detailed Usage Guide • AI-Native • Architecture • Roadmap

CI Swift Platform Concurrency OpenAPI Status


Release capabilities: Reliability and streaming and Operational readiness. Requires Swift 6.3; validated with Swift 6.3.2. Alpha.3 adds operation deadlines, graceful draining and transfer observation; see the migration guide.

Why Daylily Exists

Server-side Swift has powerful foundations.

But many frameworks still feel shaped by the pre-Concurrency era:

  • EventLoop-heavy application code.
  • Transport details leaking into user-facing APIs.
  • Runtime patterns optimized for frameworks, not products.
  • Architecture that AI agents must reverse-engineer from source.
  • Macro-first designs where the runtime truth is hard to inspect.

Daylily takes another path:

  • Swift Concurrency first.
  • Runtime-first architecture.
  • AI-native development workflow.
  • Explicit contracts over hidden magic.
  • Product-oriented developer experience.

Daylily starts small on purpose: a declarative runtime, a NIO-backed HTTP/1.1 server, and an AIDEV contract that lets AI agents understand, use, upgrade, and extend the project without first spelunking through source code.

Hello World

import Daylily

@main
@DaylilyServer
struct App {
    @GET("/hello")
    func hello() -> String {
        "Daylily ships."
    }
}

That's it.

Core Philosophy

AI-Native by Design

Daylily is built so AI agents can safely understand and extend projects.

Instead of forcing AI to infer architecture from source code alone, Daylily exposes:

  • architecture contracts;
  • API registries;
  • runtime guarantees;
  • extension playbooks;
  • project maps;
  • machine-readable metadata.

AI becomes a first-class development participant.

Runtime First

Macros are tools. Runtime truth matters more.

Daylily prioritizes:

  • observable runtime state;
  • explicit contracts;
  • deterministic architecture;
  • introspection-friendly systems.

Default Path, Not Mandatory Path

Daylily provides recommended defaults, but applications do not have to surrender their architecture to the framework.

  • The runtime DSL is a first-class API, not a fallback for when macros fail.
  • @DaylilyServer and route macros are convenience syntax over runtime routes.
  • The Dependencies registry is a default dependency channel, not a required DI container.
  • Applications may keep their own composition root, capture their own services, or register their own container.

Swift Concurrency First

Daylily is designed around modern Swift:

  • async / await;
  • Sendable;
  • structured concurrency;
  • transport boundaries that stay out of user-facing APIs.

Feature Matrix

Area Status
Swift Concurrency-native runtime Implemented
Declarative route DSL Implemented
Macro route/group declarations MVP
Typed path/query/header inputs Implemented
Typed JSON body input with @Body Implemented
Middleware Implemented
Streaming request body Implemented
JSON body and response helpers Implemented
OpenAPI generation MVP
Observability middleware MVP
Transport-free testing helpers Implemented
AIDEV AI handoff system Implemented
Dependencies registry MVP + keyed runtime
Macro @Dependency inputs Implemented
Macro middleware attributes Implemented
Explicit OpenAPI schemas and security schemes Implemented
Streaming responses and SSE Implemented
Optional query/header inputs Implemented
Full Swift schema derivation Planned

Architecture

Client / SwiftUI / Flutter / API Consumer
        |
        v
Shared DTOs and HTTP contracts
        |
        v
Daylily Runtime
        |
        +--> Route metadata --> OpenAPI
        |
        +--> AIDEV contracts --> AI agents
        |
        v
Transport layer

The runtime remains the source of truth. Macros lower into runtime routes and metadata; OpenAPI and AI tooling read the same explicit contract instead of guessing from source code.

Daylily's defaults are intentionally replaceable. When the macro shape or a built-in helper does not fit a real application, the runtime API remains the supported path.

Benchmarks

Benchmarks are in progress.

The current focus is:

  • predictable architecture;
  • concurrency correctness;
  • developer experience;
  • AI collaboration;
  • long-term maintainability.

Raw performance benchmarks will be published after the runtime and beta documentation stabilize.

Ecosystem Vision

Daylily is evolving toward a Swift cloud development experience, not only a routing library.

Potential ecosystem directions:

  • authentication;
  • realtime features;
  • queues and background jobs;
  • deployment tooling;
  • AI-assisted architecture workflow;
  • fullstack Swift patterns.

Quick Start

Use Daylily as a SwiftPM package:

.package(url: "https://github.com/sinduke/Daylily.git", from: "0.1.0-alpha.4")

The latest published prerelease is 0.1.0-alpha.4. Alpha.4 adds per-write deadlines, bounded observer delivery, nullable contracts and a persistent commerce example. Read the alpha.4 migration guide and release readiness for publication and exact-version validation status. The main README may later describe newer APIs.

Add the product to your target:

.product(name: "Daylily", package: "Daylily")

For local framework development or examples, run from source.

From the project root:

swift build
swift test
swift run HelloDaylily --check
swift run

To verify Daylily from a fresh external SwiftPM package:

scripts/consumer-smoke-test.sh --mode path
scripts/consumer-smoke-test.sh --mode release --version 0.1.0-alpha.4

To start from the recommended minimal app shape:

cp -R templates/minimal-app MyDaylilyApp
cd MyDaylilyApp
swift build
swift test
swift run App --check

To try the first real API example:

scripts/example-smoke-test.sh --mode path
cd examples/commerce-api
swift run App --check
swift run App

Daylily uses Swift Testing for the formal test target. If swift test reports no such module 'Testing' while xcode-select -p points at Command Line Tools, run it with an Xcode developer directory, for example:

DEVELOPER_DIR=/Applications/Xcode-26.5.0.app/Contents/Developer swift test

The server listens on:

http://127.0.0.1:8080

Try it:

curl http://127.0.0.1:8080/hello
curl http://127.0.0.1:8080/users/42
curl 'http://127.0.0.1:8080/search?term=daylily&page=1'
curl -H 'x-daylily: ships' http://127.0.0.1:8080/headers
curl -X POST --data 'hi' http://127.0.0.1:8080/echo
curl -X PUT --data 'full' http://127.0.0.1:8080/users/42
curl -X PATCH --data 'partial' http://127.0.0.1:8080/users/42
curl -i -X DELETE http://127.0.0.1:8080/users/42
curl -I http://127.0.0.1:8080/health
curl -i -X OPTIONS http://127.0.0.1:8080/health
printf 'abcdef' | curl --http1.1 -H 'Transfer-Encoding: chunked' -H 'Content-Length:' --data-binary @- http://127.0.0.1:8080/upload/count
curl http://127.0.0.1:8080/json/health
curl -X POST -H 'content-type: application/json' --data '{"message":"hi"}' http://127.0.0.1:8080/json/echo

Detailed Usage Guide

The rest of this README is the detailed usage guide. It keeps the concrete, copy-pasteable examples close to the project entry point.

Dedicated beta docs are also available:

README sections:

  • Current API: runtime routes, typed parameters, JSON, lifecycle, and server configuration.
  • Dependencies: app-wide default dependency registry and custom service wiring.
  • Runtime Middleware: application, group, and route middleware with one-shot body rules.
  • Observability: request ID and request logging middleware.
  • Route Metadata: explicit metadata and minimal OpenAPI generation.
  • DaylilyTesting: in-memory tests, request builders, and JSON assertions.
  • Macro API MVP: @DaylilyServer, route macros, typed inputs, and macro limits.
  • AI-Native Development: AIDEV contracts, registries, playbooks, and agent workflow.

Current API

The current runtime API looks like this:

import Daylily

struct HealthPayload: Codable, Sendable {
    let status: String
}

struct CreateUserInput: Codable, Sendable {
    let name: String
}

struct EchoPayload: Codable, Sendable {
    let message: String
}

struct EchoResponse: Codable, Sendable {
    let echo: String
}

@main
struct HelloDaylily {
    static func main() async throws {
        let app = Application {
            Get("/") {
                "Daylily is awake."
            }

            Get("/hello") {
                "Daylily ships."
            }

            Get("/users/:id") { request in
                let id = try request.parameters.require("id", as: Int.self)
                return "User \(id)"
            }

            Get("/search") { request in
                let term = try request.query.require("term", as: String.self)
                let page = try request.query.get("page", as: Int.self) ?? 1
                return "Search \(term) page \(page)"
            }

            Get("/headers") { request in
                try request.headers.require("x-daylily", as: String.self)
            }

            Get("/json/health") {
                JSON(HealthPayload(status: "ok"))
            }

            Post("/json/echo") { request in
                let input = try await request.json(EchoPayload.self)
                return JSON(EchoResponse(echo: input.message))
            }

            Post("/echo") { request in
                try await request.body.string(upTo: .kilobytes(64))
            }

            Put("/users/:id") { request in
                let id = try request.parameters.require("id", as: Int.self)
                let body = try await request.body.string(upTo: .kilobytes(64))
                return "Updated user \(id): \(body)"
            }

            Patch("/users/:id") { request in
                let id = try request.parameters.require("id", as: Int.self)
                let body = try await request.body.string(upTo: .kilobytes(64))
                return "Patched user \(id): \(body)"
            }

            Delete("/users/:id") {
                Status.noContent
            }

            Head("/health") {
                Status.ok
            }

            Options("/health") {
                Status.noContent
            }
        }

        try await app.run()
    }
}

Lifecycle hooks are available before ecosystem modules:

let app = Application {
    Get("/hello") { "ok" }
}
.configure {
    // register configuration
}
.boot {
    // open resources
}
.started {
    // server has bound successfully
}
.shutdown {
    // stop accepting work
}
.cleanup {
    // release resources
}

Explicit server configuration is available when defaults are not enough:

try await app.run(
    configuration: ServerConfiguration(
        host: "0.0.0.0",
        port: 8080
    )
)

Swift ServiceLifecycle support lives in the optional DaylilyServiceLifecycle module:

import Daylily
import DaylilyServiceLifecycle
import Logging
import ServiceLifecycle

let serviceGroup = ServiceGroup(
    services: [
        app.serviceLifecycleService()
    ],
    gracefulShutdownSignals: [.sigint, .sigterm],
    logger: Logger(label: "hello-daylily")
)

try await serviceGroup.run()

DaylilyServiceLifecycle adapts Application into a ServiceLifecycle Service. It does not replace Daylily lifecycle hooks and is not re-exported by the umbrella Daylily module. The default ServerConfiguration.serviceLifecycleDefault disables Daylily's own signal handling so ServiceGroup owns graceful shutdown signals; pass your own ServerConfiguration if you want a different policy.

Swift HTTP Types support lives in the optional DaylilyHTTPTypes module:

import Daylily
import DaylilyHTTPTypes

let request = Request(
    method: HTTPMethod("PROPFIND")!,
    path: "/items?tag=tea&tag=oolong"
)

let httpRequest = try request.httpTypesRequest()
let daylilyRequest = Request(httpTypesRequest: httpRequest)

DaylilyHTTPTypes converts between Daylily Request/Response values and Swift HTTP Types HTTPRequest/HTTPResponse values. It is not re-exported by the umbrella Daylily module. The adapter preserves custom method tokens, raw request targets, repeated headers, repeated query parameters, and HTTPTypes pseudo fields; conversions that would require lossy header/status legalization throw instead of silently changing values.

Swift OpenAPI Generator server support lives in the optional DaylilyOpenAPITransport module:

import Daylily
import DaylilyOpenAPITransport
import Foundation

let transport = DaylilyOpenAPITransport()
let handler = GeneratedAPIHandler()

try handler.registerHandlers(
    on: transport,
    serverURL: URL(string: "/api")!
)

try await transport.application().run()

DaylilyOpenAPITransport adapts OpenAPIRuntime ServerTransport registrations into Daylily routes. It is not re-exported by the umbrella Daylily module. Whole-segment generated path parameters such as {id} map to Daylily :id parameters; mixed template segments such as {name}.zip throw during registration. Generated response bodies stream by default. Use responseBodyPolicy: .collect(upTo: limit) for explicit bounded buffering.

Dependencies

Daylily includes a small app-wide Dependencies registry for common service wiring:

struct ProductService: Sendable {
    func list() async throws -> [Product] {
        []
    }
}

let app = Application(dependencies: { dependencies in
    dependencies.register(ProductService())
}) {
    Get("/products") { request in
        let service = try request.dependencies.require(ProductService.self)
        return JSON(try await service.list())
    }
}

The registry supports concrete Sendable values by type:

var dependencies = Dependencies()
dependencies.register(ProductService())

let service = try dependencies.require(ProductService.self)
let optional: ProductService? = dependencies.get()

Use typed keys when dependency intent matters more than the concrete type, such as protocol-oriented services or multiple values of the same type:

protocol ProductServing: Sendable {
    func list() async throws -> [Product]
}

extension ProductService: ProductServing {}

enum AppDependencies {
    static let productService = DependencyKey<any ProductServing>("productService")
    static let primaryDatabase = DependencyKey<Database>("database.primary")
    static let replicaDatabase = DependencyKey<Database>("database.replica")
}

dependencies.register(ProductService(), for: AppDependencies.productService)

let service = try dependencies.require(AppDependencies.productService)

Macro handlers can read keyed dependencies directly with @Dependency:

@GET("/products")
func products(
    @Dependency(AppDependencies.productService) service: any ProductServing
) async throws -> JSON<[Product]> {
    JSON(try await service.list())
}

This is a default tool, not mandatory architecture. Capturing your own services remains equally valid:

let services = MyServices()

let app = Application {
    Get("/products") { _ in
        try await services.products.list()
    }
}

For app factories, prefer domain-specific parameters first, then keep a configureDependencies escape hatch for tests and advanced wiring:

public func makeApplication(productService: ProductService = .live) -> Application {
    makeApplication(configureDependencies: { dependencies in
        dependencies.register(productService)
    })
}

public func makeApplication(
    configureDependencies: @Sendable (inout Dependencies) -> Void
) -> Application {
    Application(dependencies: configureDependencies) {
        Get("/products") { request in
            let service = try request.dependencies.require(ProductService.self)
            return JSON(try await service.list())
        }
    }
}

Tests can usually override the business service directly:

let client = TestClient(makeApplication(productService: .stub([])))

Use Dependencies Usage for the fuller pattern.

Runtime Middleware

Middleware is available at application, group, and route scope:

struct HeaderMiddleware: Middleware {
    func handle(_ request: Request, next: Handler) async throws -> Response {
        var response = try await next.respond(to: request)
        response.headers["x-daylily"] = "ships"
        return response
    }
}

let app = Application {
    Group("/api") {
        Get("/health") {
            "ok"
        }
    }
    .middleware(HeaderMiddleware())

    Get("/hello") {
        "Daylily ships."
    }
}
.middleware(HeaderMiddleware())

Order is:

application -> router dispatch -> group -> route -> handler

Middleware can read request.body, but RequestBody is one-shot. If middleware consumes the body and then calls next, downstream code sees the body as already consumed. Daylily does not perform hidden body replay.

When middleware intentionally needs to inspect body bytes and still pass an equivalent body downstream, use explicit buffering:

struct SignatureMiddleware: Middleware {
    func handle(_ request: Request, next: Handler) async throws -> Response {
        try await request.withBufferedBody(upTo: .megabytes(1)) { replayed, bytes in
            try verify(bytes)
            return try await next.respond(to: replayed)
        }
    }
}

The replacement body is still one-shot, and the helper requires an explicit size limit.

Observability

DaylilyObservability provides request ID and request logging middleware without adding logging backends or tracing dependencies to DaylilyCore:

let app = Application {
    Get("/hello") { request in
        request.daylilyRequestID ?? "missing"
    }
}
.middleware(RequestIDMiddleware())
.middleware(RequestLoggingMiddleware(sink: ConsoleRequestLogSink()))

RequestIDMiddleware always generates a Daylily-owned x-daylily-request-id. Incoming x-request-id is treated as external correlation data, not as Daylily's unique request identity. When no incoming x-request-id exists, Daylily writes its generated request ID to x-request-id for ecosystem compatibility.

RequestLoggingMiddleware records method, path, final status, request ID, external correlation ID, duration, and public error reason. InMemoryRequestLogSink is available for behavior checks and early tests.

SwiftLog support lives in the optional DaylilySwiftLog module:

import Daylily
import DaylilySwiftLog

let app = Application {
    Get("/hello") {
        "Daylily ships."
    }
}
.middleware(
    RequestLoggingMiddleware(
        sink: SwiftLogRequestLogSink(label: "hello-daylily")
    )
)

DaylilySwiftLog adapts RequestLog into SwiftLog metadata without replacing RequestLoggingMiddleware. It does not call LoggingSystem.bootstrap(...), and it is not re-exported by the umbrella Daylily module.

Route Metadata

Routes can carry runtime metadata without requiring the OpenAPI generator to guess from source code:

let app = Application {
    Post("/users") {
        Status.created
    }
    .describe(
        summary: "Create user",
        tags: ["Users"],
        inputs: [
            .header("x-daylily", type: "String"),
        ],
        requestBody: .json("CreateUserInput"),
        responses: [
            .response(.created, contentType: "application/json", type: "UserResponse"),
        ]
    )
}

let document = app.openAPI(title: "Daylily Demo", version: "0.1.0")

DaylilyOpenAPI maps route metadata into a minimal OpenAPI document. It converts Daylily path parameters such as /users/:id into OpenAPI paths such as /users/{id}.

The document is Codable, so it can use the existing JSON(...) response wrapper:

let response = JSON(document)

This is still an MVP. Deep schema derivation from Swift types is intentionally deferred.

DaylilyTesting

DaylilyTesting provides transport-free test helpers:

import Daylily
import DaylilyTesting

let app = Application {
    Get("/hello") {
        "Daylily ships."
    }
}

let response = try await TestClient(app).get("/hello")

try response.requireStatus(.ok)
try response.requireBody("Daylily ships.")

It also includes request builders and JSON assertions:

struct EchoPayload: Codable, Equatable, Sendable {
    let message: String
}

struct EchoResponse: Codable, Equatable, Sendable {
    let echo: String
}

let request = try TestRequest
    .post("/json/echo")
    .withJSON(EchoPayload(message: "hi"))

let jsonResponse = try await TestClient(app).send(request)

try jsonResponse.requireStatus(.ok)
try jsonResponse.requireJSON(EchoResponse(echo: "hi"))

TestClient calls Application.respond(to:) directly, so tests exercise the same in-memory runtime behavior without opening a socket.

Macro API MVP

Daylily's macro MVP supports this shape:

import Daylily

struct HealthPayload: Codable, Sendable {
    let status: String
}

struct CreateUserInput: Codable, Sendable {
    let name: String
}

struct ResponseHeaderMiddleware: Middleware {
    let name: String
    let value: String

    func handle(_ request: Request, next: Handler) async throws -> Response {
        var response = try await next.respond(to: request)
        response.headers[name] = value
        return response
    }
}

enum AppMiddleware {
    static let observability = ResponseHeaderMiddleware(name: "x-daylily-app", value: "observed")
}

@main
@Use(AppMiddleware.observability)
@DaylilyServer
struct App {
    @GET("/hello")
    func hello() -> String {
        "Daylily ships."
    }

    @Use(ResponseHeaderMiddleware(name: "x-daylily-route", value: "users"))
    @Security("bearerAuth")
    @GET("/users/:id")
    func user(@Path id: Int) -> String {
        "User \(id)"
    }

    @GET("/accounts/:id")
    func account(@Path("id") accountID: Int) -> String {
        "Account \(accountID)"
    }

    @GET("/health")
    func health() -> JSON<HealthPayload> {
        JSON(HealthPayload(status: "ok"))
    }

    @POST("/users")
    func create(@Body input: CreateUserInput) -> Status {
        .created
    }

    @PUT("/users/:id")
    func update(@Path id: Int, req: Request) async throws -> String {
        "updated"
    }

    @PATCH("/users/:id")
    func patch(@Path id: Int, req: Request) async throws -> String {
        "patched"
    }

    @DELETE("/users/:id")
    func delete(@Path id: Int) -> Status {
        .noContent
    }

    @HEAD("/health")
    func head() -> Status {
        .ok
    }

    @OPTIONS("/health")
    func options() -> Status {
        .noContent
    }

    @GET("/search")
    func search(
        @Query term: String,
        @Query("page") pageNumber: Int,
        @Header("x-daylily") token: String
    ) -> String {
        "\(term):\(pageNumber):\(token)"
    }

    @Use(ResponseHeaderMiddleware(name: "x-daylily-group", value: "api"))
    @GROUP("/api")
    struct API {
        @GET("/health")
        func health() -> String {
            "ok"
        }
    }
}

The rule is simple: macros must lower into the runtime route system. The runtime remains the source of truth.

Macro APIs are a default convenience path, not the only supported way to build a Daylily app. If a project needs a custom composition root, non-default initialization, or a handler shape outside the macro MVP, use the runtime DSL directly.

Typed macro inputs also lower into runtime route behavior. @Path, @Query, @Header, and preferred @Body inputs contribute OpenAPI-ready metadata through the same Route.describe(...) model used by handwritten routes. @JSONBody is retained as a compatibility alias spelling for @Body. @Dependency lowers to keyed Request.dependencies.require(...) and does not contribute route metadata.

Macro middleware uses the same runtime middleware model. @Use(...) is supported on the @DaylilyServer type, @GROUP nested structs, and route methods. Its argument is one Swift expression, so named values such as AppMiddleware.observability work without a separate registry.

Security metadata is explicit. @Security("bearerAuth") contributes OpenAPI operation security metadata through Route.describe(security:); it is not inferred from middleware.

Macro apps can define a dependency configuration hook:

func configureDependencies(_ dependencies: inout Dependencies) {
    dependencies.register(ProductService(), for: AppDependencies.productService)
}

MVP limits:

  • handlers must be instance methods;
  • the server type must be default-initializable with Self();
  • handlers may use zero parameters, one Request parameter, @Path, @Query, @Header, @Dependency, and one @Body parameter, with @JSONBody accepted as a compatibility alias spelling;
  • @Path lowers into req.parameters.require(_:as:);
  • @Path names must match :name route segments;
  • required @Query and @Header lower into require(_:as:); optional values lower into get(_:as:) with required: false metadata;
  • @Body lowers into try await req.json(Type.self); @JSONBody is a compatibility alias spelling with the same lowering;
  • @Dependency(key) lowers into try req.dependencies.require(key);
  • @Use(middleware) lowers into runtime .middleware(middleware) and can be applied at app, group, or route scope;
  • @Security("scheme") lowers into route security metadata and OpenAPI operation security;
  • the raw one-shot request body type is RequestBody;
  • grouped types must be default-initializable;
  • optional query/header inputs support T?, Optional<T>, and Swift.Optional<T>; optional paths are rejected;
  • keyless dependency inference and deep OpenAPI schema derivation are future work.

These are macro MVP limits, not runtime limits.

AI-Native Development

Daylily is designed so an AI agent can become useful quickly.

Instead of asking AI to guess the architecture from scattered source files, the project contains an explicit AIDEV system:

This means a user can ask an AI to:

  • explain how Daylily works;
  • add a new HTTP verb;
  • extend JSON support;
  • design middleware;
  • implement macros;
  • update the public API registry;
  • write or update checks;
  • validate the project with the known commands.

The AI does not need to rediscover the project from scratch. It starts from the AIDEV contract, makes a scoped change, updates the contract if needed, and runs validation.

Project Layout

Daylily/
├── AIDEV.md
├── DAYLILY_NOTES.md
├── Package.swift
├── README.md
├── README.zh-CN.md
├── docs/
├── Sources/
│   ├── Daylily/
│   ├── DaylilyCore/
│   ├── DaylilyJSON/
│   ├── DaylilyNIO/
│   ├── DaylilyObservability/
│   ├── DaylilyOpenAPI/
│   ├── DaylilyTesting/
│   ├── DaylilyCheckSuite/
│   └── HelloDaylily/
├── Tests/
│   └── DaylilyTests/
└── ai/
    ├── epics/
    ├── aidev/
    ├── prompts/
    └── tasks/

Architecture Rules

The most important invariants:

  • DaylilyCore must not depend on NIO.
  • User-facing APIs must not expose NIO types.
  • Runtime APIs come before macro sugar.
  • swift run should keep starting the example server.
  • swift test should keep passing.
  • swift run HelloDaylily --check should keep passing.
  • Public API changes must update AIDEV.

Roadmap

Near-term:

  1. Harden the optional ecosystem adapter set through consumer feedback.
  2. Continue OpenAPI schema expansion and security scheme components after the macro/runtime bridge stays stable.

Operational validation (alpha.3 sources)

python3 ai/evals/contracts/test_compatibility.py
scripts/contract-regression-test.sh --mode path
python3 scripts/deployment-trial.py --duration 300 --artifacts /tmp/daylily-deployment

The deployment command requires Docker and a new/empty artifact directory. It runs two Linux replicas behind Caddy with loopback-only host ports, verifies SSE and rolling shutdown, and removes its own resources. See the guide for defaults, commands, evidence, and limits. Actual model-edit trials are opt-in and consume the user's configured Codex account; they are not part of automatic CI.

License

Daylily is released under the MIT License.

Alpha.4 capability validation (0026)

The execution checklist covers persistent commerce, bounded runtime resources, nullable contracts, sustained external Linux deployment and broader AI edits. Current API and ownership semantics: candidate guide. All priorities and integration are verified; see acceptance results.

scripts/persistent-consumer-smoke-test.sh --mode path
python3 scripts/persistent-commerce-smoke-test.py --help
python3 scripts/sustained-deployment-trial.py --duration 3600 --artifacts /new/empty/daylily-business
python3 ai/evals/repeated-changes/run_extended.py --baseline-only --repetitions 1 --output /new/empty/ai-baselines

The persistent consumer also accepts exact revision/release sources and records resolver pins. The actual database harness requires Docker. CI adds macOS/Linux persistent consumers and a private TLS/database Linux trial; workflow dispatch with business_trial_seconds=3600 supplies the one-hour acceptance run. Ordinary CI uses 60 seconds. Baseline-only AI checks make no model calls. Actual run_extended.py without --baseline-only is opt-in and uses the configured Codex account; published trial evidence records token usage, unknown monetary cost and all repair attempts.

About

No description, website, or topics provided.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages