capsule AI-native Unix-like composition layer

capsule.yaml

2,349 bytes · 78 lines · capsule://quake0day/[email protected] raw on github

apiVersion: capsule.dev/v0.1
kind: Capsule

name: yingjieli-public-site
version: 1.0.0
type: subsystem
domain: yingjieli.site

maintainers:
  - name: Quake
    email: [email protected]

purpose:
  summary: |
    The public, read-only frontend of yingjieliartist.com. Renders the
    hero, biography, masonry gallery of works, exhibitions, and contact
    sections, plus a keyboard / touch-friendly lightbox. Pulls all
    content at runtime from /api/data and all images from /api/img/<key>.
  owns:
    - index.html (markup, SEO meta, OpenGraph)
    - "assets/styles.css (design system: Fraunces + Inter Tight, paper palette)"
    - assets/app.js (masonry layout + lightbox + nav scroll)
    - robots.txt + sitemap.xml
    - the visual contract of the site (typography, palette, motion)
  does_not_own:
    - content data (consumes GET /api/data; never mutates it)
    - image bytes (consumes /api/img/<key>; never uploads)
    - authentication (never reads or sets the yl_admin cookie)
    - admin UI (separate capsule)

interfaces:
  provides:
    - kind: http_api
      name: site-root
      entrypoint: src/index.html

  requires:
    - kind: http_api
      name: data-read
      from_capsule: yingjieli-content-store
    - kind: http_api
      name: image-serve
      from_capsule: yingjieli-image-store

dependencies:
  capsules:
    - name: yingjieli-content-store
      version: ">=1.0.0 <2.0.0"
    - name: yingjieli-image-store
      version: ">=1.0.0 <2.0.0"
  runtime:
    - cloudflare-pages: "*"

agent:
  summary_for_ai: |
    Read-only frontend. All content fetched from /api/data on load;
    page is built from that JSON, not data embedded in HTML. If you add
    a new section, you also need a new field in content-store's
    DEFAULT_DATA and a new card in the admin UI.

  avoid:
    - Hard-coding content (artwork lists, bios) in HTML.
    - Importing jQuery or any heavy framework — the site is 0-dep JS by design.

verification:
  health_checks:
    - id: index-html-present
      command: node -e "require('fs').statSync('src/index.html')"
    - id: app-js-present
      command: node -e "require('fs').statSync('src/assets/app.js')"

  invariants:
    - The public site never mutates content (no PUT/POST/DELETE in app.js).
    - The public site never reads the yl_admin cookie.

x-reconstruct:
  install: install.json