factory0.ventures · FZ/01
Factory Zero is an AI-native venture studio. It creates, launches and operates companies through a shared network of autonomous agents.
The company is becoming software. Software automated the worker. Agents automate the organization. The traditional company coordinates humans. The AI-native company coordinates intelligence.
Historically, software automated individual workflows. The next step is software coordinating the organization itself. Factory Zero builds real companies around that transition.
Factory Zero OS runs as five layers. Each function in each layer is an agent.
| Layer | Agents |
|---|---|
DISCOVER |
Research · Strategy · Analytics |
BUILD |
Product · Engineering · Design · QA |
OPERATE |
Infrastructure · Security · Support · Finance |
DISTRIBUTE |
Growth · Content · Sales |
LEARN |
Legal · Knowledge · Optimization |
Every venture inherits the same foundation, so nothing is rebuilt. Identity, payments and billing, analytics, deployment, observability, agent orchestration, customer support, marketing automation, finance, knowledge, security, experimentation and internal tooling are all shared.
Each venture runs with its own brand, product, customers, data boundaries and strategy.
FZ-001 Kontinuum. An AI composer performing on a deterministic real-time engine. Music written and performed continuously, personalised to the listener, and playable offline. Not a streaming app and not a DAW: a living instrument. Currently at prototype stage, with no public surface yet.
SIGNAL → VALIDATION → PROTOTYPE → LAUNCH → AUTONOMY → SCALE
| Level | ||
|---|---|---|
LEVEL 0 |
Human-operated | |
LEVEL 1 |
AI-assisted | |
LEVEL 2 |
Agent workflows | |
LEVEL 3 |
Agent-operated | target |
LEVEL 4 |
Self-optimizing | target |
LEVEL 5 |
Autonomous company | target |
Ventures are designed to run at levels 3 to 5. Humans can intervene at every level, and a named human is accountable for every venture.
HUMAN LAYER |
AGENT LAYER |
|---|---|
| Mission · Capital · Governance · Judgment | Research · Build · Operate · Optimize |
| Humans define mission, capital, ethics, ownership, risk boundaries, high-impact decisions and relationships. | Agents execute within those boundaries. Every action is logged, observable and reversible. |
This repo is the Factory Zero marketing site. Static HTML, CSS and vanilla JavaScript. No build step, no framework, no dependencies. Serve the directory and it runs.
It was implemented from the Claude Design source Factory Zero.dc.html, which
targets the dc-runtime preview environment (<x-dc> templates, {{ }}
bindings, <sc-for> loops, a React DCLogic class). That runtime is a
design-time dependency, so the component logic was ported to plain JavaScript.
Timings, easing, canvas geometry, colour thresholds and copy carry over
unchanged.
index.html home
ventures/index.html the venture registry
system/index.html three-layer architecture + design principles
thesis/index.html the working paper, 7 sections
about/index.html what Factory Zero is and is not
enter/index.html access request
404.html styled not-found page
assets/
fz.css design tokens and every component style
fz-data.js ← venture data lives here (single source of truth)
fz-common.js loaded on every page
fz-app.js home: hero canvas, rolling log, agent rotation
fz-hero3d.js home: the 3D venture network (plain WebGL2, no library; loads after `load`, falls back to the 2D canvas)
fz-ventures.js registry selection and the FZ STACK filter
fz-timeline.js home: plays the venture timeline
timeline-data.json org creation dates and commits per day (counts only)
fz-enter.js access-request form
kontinuum-animated.svg FZ-001 brand mark (animated, self-contained)
favicon.svg
og.png, og-*.png per-page 1200x630 Open Graph cards (generated)
readme-banner.png the banner above (generated)
apple-touch-icon.png, icon-512.png
robots.txt allows AI and answer-engine crawlers explicitly
sitemap.xml all six pages
llms.txt plain-text summary for machine readers
stack.json what each venture is built with (generated)
site.webmanifest
_headers Cloudflare Pages response headers
.well-known/
security.txt RFC 9116
tools/
og-render.html OG card template (takes ?t=&k=&s= overrides)
banner-render.html README banner
render-og.sh regenerates every raster asset
sync-ventures.js writes fz-data.js into the static HTML
timeline.js draws the home-page venture timeline (used by sync-ventures.js)
sync-timeline.js rebuilds timeline-data.json from the GitHub API
build-dist.sh assembles dist/ (allowlist + cache-bust stamping)
python3 -m http.server 8099
# → http://127.0.0.1:8099/Paths are absolute (/assets/...), so open it through a server rather than
file://.
Nearly everything is data:
assets/fz-data.jsholdsventuresandlayers(the agent grid; each agent's line says what it does, never a made-up event or number). Add real ventures there. The pipeline, the branch list and the hero counters all derive from that array.- After editing
ventures, runnode tools/sync-ventures.js. The registry rows and the default detail panel are written intoventures/index.htmlandsystem/index.htmlas static HTML so they are indexable with JavaScript off. That script regenerates them fromfz-data.js, which stays the only place venture data is authored. It only rewrites the regions between the<!-- fz:*:start -->/<!-- fz:*:end -->markers. The same run writes one page per venture atventures/<slug>/index.html(the registry with that record selected, plus its own title, description and canonical URL), the venture entries insitemap.xml, andfunctions/api/activity-sources.json. Commit all of it; never edit the generated venture pages by hand. - What each venture is built with is the
usesarray on its record inassets/fz-data.js: sister ventures by id (FZ-013) and third parties by a key ofservices(polar,cloudflare,google-fonts,aws-ses, …), each with a role (framework,email,support,bug-reports,payments,security-screening,secrets-handoff,agents,deploys,fonts,hosting) and a status,live(in use today, and checked) orplanned.sync-ventures.jsrenders it as the "Built with" row on each venture page and writes/stack.json, which each venture site vendors into a footer strip and its subprocessors list with its owntools/script (no runtime fetch). An unknown id, role or status stops the sync. The evidence for every entry is intools/STACK-SOURCES.md(not published); update it with the entry, and never mark an entrylivewithout a check you could repeat. - The venture timeline on the home page (under the venture reel) is static
SVG that
sync-ventures.jsdraws fromassets/timeline-data.json: one row per venture, its logo on the day its GitHub org was created, ticks for its commits per day. The file holds counts only, never repository names; private repositories count by number, as in the activity chart. Refresh it withnode tools/sync-timeline.js(needsghlogged in; it rewrites the data and rerunssync-ventures.js).assets/fz-timeline.jsplays it as a slow sweep once it is in view; with JavaScript off or motion reduced the finished chart shows. - GitHub activity. The detail panel charts weekly commits and issues (open count, opened/closed per week, the five newest open ones; titles that look like security reports are left out of that list) across a
venture's public repositories (its
githublinks; an owner-only link means all of that owner's public, non-fork repositories).functions/api/activity.jsfetches them from GitHub and keeps the last good result in Workers KV (bindingACTIVITY, declared inwrangler.toml). Visitors are always served that copy; once it is a day old the next request refreshes it in the background, and a failed refresh keeps the old copy and retries in 10 minutes, so a GitHub outage or expired token makes the chart older, never empty. - Private repositories count, by number only. With the
GH_APP_IDandGH_APP_PRIVATE_KEY(PKCS#8 PEM) Pages secrets set, every venture org that installed the read-only Factory Zero Activity GitHub App (Metadata: read, Issues: read) is read through that app, so its private repositories add to the commit and issue totals. Private repository names, issue titles and links are never published: the issue list shows public repositories only and error messages carry status codes, not names. Orgs without the app count public repositories only. Set it up withnode tools/setup-github-app.mjs(creates the app, stores both secrets without writing the key to disk, opens the install page); after a deploy,node tools/setup-github-app.mjs --refreshmakes every venture refetch. It only queries the owners and repositories inactivity-sources.json. Set aGITHUB_TOKENPages secret (a fine-grained token with no permissions is enough) to lift GitHub's 60-requests-an-hour anonymous limit. window.FZ_CONFIGat the bottom of the same file holds the headline and factory status. These mirror the editabledata-propsfrom the design source; the headline is also written statically inindex.html.- The hero proof row (ventures, sectors, ventures that already run on a
sister venture) is counted from
venturesbysync-ventures.jsand written between thefz:proofmarkers inindex.html. "Run on a sister venture" counts records with at least oneusesentry that names another venture and islive, so aplannedlink never inflates it. - All prose (thesis, human role, footer) is plain HTML in
index.html.
./tools/render-og.shUses headless Chrome. ImageMagick cannot rasterize these correctly on macOS: it silently falls back to its internal renderer and drops colour.
| File | Purpose |
|---|---|
llms.txt |
Structured plain-text summary for LLM readers |
robots.txt |
Explicit allow for GPTBot, ClaudeBot, PerplexityBot, Google-Extended and others |
JSON-LD in index.html |
Organization, WebSite, WebPage, and a DefinedTermSet for the autonomy levels |
og.png, og-*.png |
A 1200x630 card per page, generated from the real hero visual |
| JSON-LD per page | Page type plus BreadcrumbList; the thesis also emits an Article |
| Directory-style URLs | /ventures/ rather than /ventures.html, so nothing needs redirecting later |
.well-known/security.txt |
RFC 9116 contact |
Three deliberate changes, each fixing something that did not work in the preview runtime:
style-hover. The design source setsstyle-hover="..."on the footer CTA and pipeline units, butdc-runtimeimplements no such attribute, so those hovers never fired. Reimplemented as real CSS:hover.fzScan. The pipeline scan line animatedtranslateY(-100%)totranslateY(100%)on a 120px band, so it only ever travelled 240px inside a much taller grid. Reimplemented withbackground-positionso it sweeps the full container height.- Responsive behaviour. The design is desktop-only. Added a wrapping
header, stacking breakpoints,
minmax(min(Npx, 100%), 1fr)andmin-width: 0on grid tracks. Verified: no horizontal overflow from 320px to 1440px.
/enter/ posts JSON to functions/api/contact.js, a Cloudflare Pages Function
that verifies Turnstile and sends the mail through Owlpost (POST https://api.owlpost.to/v1/emails, Factory Zero's own email API, FZ-013) on the
transactional stream, with an Idempotency-Key derived from the submission so
a retry or double submit is mailed once.
Security properties, since this is a public unauthenticated endpoint:
| Concern | How it is handled |
|---|---|
| Open relay | The recipient is fixed server-side. It is never read from the request. |
| Secret exposure | OWLPOST_API_KEY and TURNSTILE_SECRET are Pages secrets (encrypted). Only the public Turnstile sitekey appears in the HTML. |
| Bots | Cloudflare Turnstile, verified server-side, plus an off-screen honeypot field that is silently accepted so bots learn nothing. |
| Flooding | A zone rate-limit rule: 3 POSTs per 10s per IP. |
| Header injection | Every value that could reach a mail header is stripped of CR, LF and NUL. |
| DMARC | from is always our own verified domain. The submitter's address goes in reply_to only, never in from. |
| Cross-origin abuse | Requests with a foreign Origin are rejected. |
| Oversized input | Body capped at 20KB, message at 5,000 chars. |
| Information leak | Client errors are generic. Detail is logged server-side only. |
If Owlpost is unreachable or unconfigured the form falls back to showing
contact@factory0.ventures rather than pretending the message was sent.
Setup that is not in this repo (do not commit any of it):
npx wrangler pages secret put OWLPOST_API_KEY --project-name factory-zero
npx wrangler pages secret put TURNSTILE_SECRET --project-name factory-zeroOptional overrides, as plain Pages env vars: CONTACT_TO (default
contact@factory0.ventures), CONTACT_FROM (default
noreply@send.factory0.ventures) and OWLPOST_BASE_URL (default
https://api.owlpost.to).
The sending domain must be verified in Owlpost, and this is the part with a
trap. Verify the subdomain send.factory0.ventures, not the apex.
Verifying the apex puts sending records on factory0.ventures itself, and an
MX there would displace Cloudflare Email Routing and break inbound mail to
contact@factory0.ventures. Using a subdomain keeps the two entirely separate.
Twenty-three ventures are listed, and all twenty-three are real and named:
| Venture | Stage | Target | Site | Source | |
|---|---|---|---|---|---|
FZ-001 |
Kontinuum | PROTOTYPE |
L4 | kontinuum.audio | Kontinuum-ai/kontinuum-engine |
FZ-002 |
Undercover Rockstars | LAUNCH |
L3 | undercoverrockstars.com | Undercover-Rockstars/website |
FZ-003 |
Yoginini | VALIDATION |
L3 | yoginini.us | Yoginini/website |
FZ-004 |
Cratefield | VALIDATION |
L4 | cratefield.com | Cratefield/harness |
FZ-005 |
VibeCaddie | VALIDATION |
L5 | vibecaddie.com | VibeCaddie/website |
FZ-006 |
Colonizer | PROTOTYPE |
L4 | colonizer.dev | Colonizer-dev/harness |
FZ-007 |
FindsYou.work | VALIDATION |
L4 | findsyou.work | FindsYou-Work/website |
FZ-008 |
SupportGenius | VALIDATION |
L4 | supportgeni.us | SupportGenius/website |
FZ-009 |
promptdecode | VALIDATION |
L4 | promptdeco.de | PromptDecode/website |
FZ-010 |
Groove Guru | VALIDATION |
L4 | groove.guru | Groove-Guru/website |
FZ-011 |
PosPlugin | VALIDATION |
L4 | posplug.in | POSplugin/website |
FZ-012 |
Keep Shipping | VALIDATION |
L4 | keepshipping.run | Keep-Shipping/website |
FZ-013 |
Owlpost | VALIDATION |
L4 | owlpost.to | Owlpost-to |
FZ-014 |
Bloodrank | VALIDATION |
L3 | bloodrank.dev | Bloodrank |
FZ-015 |
ratecla.im | VALIDATION |
L4 | ratecla.im | Rateclaim |
FZ-016 |
Sealbin | VALIDATION |
L4 | sealb.in | sealbin |
FZ-017 |
release.show | VALIDATION |
L4 | release.show | Release-Show |
FZ-018 |
Living Brain | VALIDATION |
L4 | livingbrain.wiki | Livingbrain-wiki/livingbrain |
FZ-019 |
Shoal | VALIDATION |
L4 | shoal.ing | shoal-ing/website |
FZ-020 |
Tokker | VALIDATION |
L4 | tokker.dev | Tokker-dev/tokker |
FZ-021 |
Ledgers | VALIDATION |
L4 | ledgers.sh | Ledgers-sh |
FZ-022 |
Ghostwritin' | VALIDATION |
L4 | ghostwrit.in | Ghostwritin |
FZ-023 |
Squeezin | VALIDATION |
L4 | squeez.in | Sqeezin |
autonomy is null on every one of them: no venture has a measured figure,
and the registry does not show one. Set a figure in fz-data.js when there
is one. What each record shows instead:
target: the autonomy level (0–5) the venture is designed to reach. A stated aim, labelledAUTONOMY TARGET, never a measurement.aims.operate,aims.intelligence,aims.growth: in words, what the venture should run on its own, the kind of intelligence that takes, and what will count as growth. The growth line names what gets counted, not a count.github: public repositories only. Private backends are not linked.
Nothing else is listed: the registry shows only what exists, so a venture with nothing public yet does not get a placeholder row.
None of the twenty-three can be bought from today, and their records and llms.txt
say so, and do not let any of them read as shipped.
Nothing on the home page is simulated. The FZ/LOG panel shows real public
GitHub activity across the ventures (merged pull requests and opened issues,
newest first, each linking to GitHub) from functions/api/log.js, and the
hero's "PRS MERGED · 30D" is the count of merged pull requests in the ventures'
public repositories over the last 30 days, from the same endpoint. Both are
cached in KV (log:v1) and refreshed every 15 minutes. Only public
repositories are searched, so no private name or title can appear. The
venture timeline under the reel is a dated snapshot of commit counts, private
repositories included by number only; its date range is printed above it.
Live at https://factory0.ventures, on Cloudflare Pages (project
factory-zero, account "Kontinuum"). www 301s to the apex via a Single
Redirect rule.
Deploys are direct upload, not git-connected:
./tools/build-dist.sh
npx wrangler pages deploy dist --project-name factory-zero --branch maintools/build-dist.sh assembles dist/ from an explicit allowlist, so repo
tooling (tools/, README.md, .git) can never end up on the site. It also
stamps every CSS/JS reference with a short content hash (?v=…). That matters:
asset filenames are not versioned in the repo, so without the stamp a deploy
cannot invalidate a cached file and visitors keep running the old JavaScript.
With it, _headers can cache /assets/*.css and *.js immutably.
dist/ is gitignored. The repo root stays the thing you serve locally, with
no build step.
Other notes:
- Cloudflare Email Routing already handles
contact@factory0.ventures(MX, SPF, DKIM and DMARC records exist on the zone). Do not disturb those. - HSTS is deliberately not set in
_headers. Turn it on in the Cloudflare dashboard (SSL/TLS, Edge Certificates) where it can be rolled back. - To connect git deploys instead, link the repo in the Pages dashboard with
build command
./tools/build-dist.shand output directorydist.
GitHub Pages was enabled briefly while this repo was named
Factory-Zero.github.io; it has been deleted and the repo renamed to website.
