Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
32b84f4
Migrate SPEC.md files to the new sdd.md template: root, package, .git…
claude Aug 20, 2026
065b814
Migrate SPEC.md files to the new sdd.md template: src core and driver
claude Aug 20, 2026
37118a1
Migrate SPEC.md files to the new sdd.md template: src utilities and p…
claude Aug 20, 2026
3071a94
Migrate SPEC.md files to the new sdd.md template: dashboard component…
claude Aug 20, 2026
33c4b48
Migrate SPEC.md files to the new sdd.md template: src daemon, CLI, co…
claude Aug 20, 2026
97defde
Migrate SPEC.md files to the new sdd.md template: store, e2e, scripts…
claude Aug 20, 2026
0e3922e
Migrate SPEC.md files to the new sdd.md template: dashboard lib (Q-Z …
claude Aug 20, 2026
a866ca5
Migrate SPEC.md files to the new sdd.md template: dashboard lib (A-Q)
claude Aug 20, 2026
891d85d
Migrate SPEC.md files to the new sdd.md template: src quota, tickets,…
claude Aug 20, 2026
051eb93
Migrate SPEC.md files to the new sdd.md template: dashboard component…
claude Aug 20, 2026
29c37d9
Migrate SPEC.md files to the new sdd.md template: daemon dashboard re…
claude Aug 20, 2026
84d8fbb
Migrate SPEC.md files to the new sdd.md template: dashboard component…
claude Aug 20, 2026
a7d45cf
Migrate SPEC.md files to the new sdd.md template: dashboard root, ui,…
claude Aug 20, 2026
dfe65ea
Migrate SPEC.md files to the new sdd.md template: daemon dashboard re…
claude Aug 20, 2026
70977f1
Merge main: adopt cloud-work and project-errors spec updates into the…
claude Aug 20, 2026
b560f9d
Review round: drop user stories derived from the removed watch relay
claude Aug 20, 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
4 changes: 2 additions & 2 deletions .github/SPEC.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
GitHub configuration for the repo; its only content is `workflows/` — the three Actions workflows.

## Before writing SPEC.md files
## Before modifying/creating SPEC.md files

Read https://raw.githubusercontent.com/brillout/sdd/refs/heads/main/sdd.md
You must always read and respect https://raw.githubusercontent.com/brillout/sdd/refs/heads/main/sdd.md
12 changes: 8 additions & 4 deletions .github/workflows/SPEC.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
The repo's GitHub Actions workflows: continuous integration, the dispatchable agent runner, and website deployment.

## TLDR
## Flows

- `framework-agent.yml` is the only workflow that is part of the product runtime — the daemon dispatches it to run agent turns on cloud runners; the rest is repo plumbing.
- `ci.yml` builds, typechecks, and tests every push and PR; `website-deploy.yml` publishes the-framework.ai. There is no release workflow: the package is unversioned and unpublished, so there is nothing to cut.
- `ci.yml` builds, typechecks, and tests every push and PR; `website-deploy.yml` publishes the-framework.ai.

## Before writing SPEC.md files
## Rationales

Read https://raw.githubusercontent.com/brillout/sdd/refs/heads/main/sdd.md
- There is no release workflow: the package is unversioned and unpublished, so there is nothing to cut.

## Before modifying/creating SPEC.md files

You must always read and respect https://raw.githubusercontent.com/brillout/sdd/refs/heads/main/sdd.md
18 changes: 14 additions & 4 deletions .github/workflows/framework-agent.SPEC.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
The workflow the product dispatches to run one coding-agent turn on a disposable GitHub-hosted runner — how an agent runs "elsewhere" on GitHub Actions.

## TLDR
## User Stories

- One dispatch is one agent turn. The daemon's driver generates a correlation id and finds its own run by it — GitHub's dispatch call never reveals which run it started.
- The run spends the user's own driver subscription, not an API key, and the agent runs unrestricted because the runner is disposable.
- The user runs an agent on a fresh GitHub Actions runner instead of their own machine, and follows it from the same dashboard.

## Flows

- One dispatch is one agent turn. The daemon tags the run with a correlation id of its own making and finds the run by that tag.
- The run spends the user's own driver subscription, not an API key, and the agent runs unrestricted.
- The turn's work — including anything left uncommitted — is pushed to the branch the driver chose, so the next turn continues exactly where this one stopped.
- The transcript comes back as an uploaded artifact, the only channel out of a run; a failed turn still uploads it, which is exactly when it's most wanted.
- The transcript comes back as an uploaded artifact, the only channel out of a run; a failed turn still uploads it.

## Rationales

- The daemon invents its own correlation id because GitHub's dispatch call never reveals which run it started.
- The agent runs unrestricted because the runner is disposable: nothing on it outlives the turn.
- A failed turn still uploads its transcript because a failure is exactly when the transcript is most wanted.

## Before modifying/creating SPEC.md files

Expand Down
17 changes: 13 additions & 4 deletions SPEC.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
Autonomous AI programming: humans make the important decisions while The Framework runs coding agents unattended — planning its own work, spending idle subscription quota on the roadmap, and handing everything off as pull requests for review.

## TLDR
## User Stories

- The product is a local daemon plus a dashboard. You register your repos, and from then on coding agents (Claude Code today, others behind the same driver seam) work on them: each agent gets a throwaway copy of the repo, does its work, and hands the result off as a pull request. Your own checkout is never touched.
- The user activates a repo from the dashboard; from then on coding agents work on it in throwaway copies, and the user's own checkout is never touched.
- The user types a prompt or picks a preset, then watches the agent live — answering the questions it parks on, chatting with it, stopping it — or is not there at all.
- The user reviews finished work as pull requests: an agent that produced real work pushes it and opens a PR by itself.
- The user walks away and the product keeps working: it drains the confirmed queue, refills it by triaging and planning tickets, fixes red CI on its own PRs, and merges them on green.
- The user never budgets: unattended work spends only the share of the subscription week that has already elapsed, and work the user asks for is never starved.
- The user runs agents on another machine, a GitHub Actions runner, or a Claude cloud session, follows them from the same dashboard, and answers the questions they park on — a browser extension bridges claude.ai cloud sessions back to it.
- The user is notified — browser or Discord — whenever an agent needs a human.

## Flows

- The product is a local daemon plus a dashboard. The user registers repos, and from then on coding agents (Claude Code today, other CLIs pluggable behind the same driver interface) work on them: each agent gets a throwaway copy of the repo, does its work, and hands the result off as a pull request.
- The human's job shrinks to decisions: answer the questions an agent parks on, accept or reject proposed tickets, review PRs. Everything else — picking the next task, triaging, planning, fixing red CI, merging on green — the daemon does by itself when nobody is at the keyboard, as long as the account's quota allows it.
- The driver is a black box: The Framework prompts it, lets it run a full turn, then reads the code and the turn's final message. It never micro-manages individual tool calls, and the CLI keeps its own subscription login — The Framework adds orchestration, not another AI bill.
- Two satellites complete the family: a browser extension that bridges claude.ai cloud sessions back to the daemon, and the product's website.
Expand All @@ -17,8 +27,7 @@ graph TD
end
```

The arrow points one way — the dashboard renders the product — and nothing depends "up". It used to
be a package boundary; the dependency survived the merge, the boundary did not.
The arrow points one way — the dashboard renders the product — and nothing depends "up".

## Rationales

Expand Down
2 changes: 1 addition & 1 deletion packages/SPEC.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
The published family: the product (`the-framework`, which carries its own dashboard UI in `dashboard/`), the claude.ai browser extension (`chrome-extension`), and the product's website (`the-framework.ai`). Nothing depends up.
The published family: the product (`the-framework`, which carries its own dashboard UI in `dashboard/`), the claude.ai browser extension (`chrome-extension`), and the product's website (`the-framework.ai`) — nothing depends up.

## Before modifying/creating SPEC.md files

Expand Down
20 changes: 16 additions & 4 deletions packages/chrome-extension/SPEC.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
A Chrome extension bridging Claude Code cloud sessions on claude.ai to the local dashboard: the question a parked session is waiting on travels home, and the answer picked in the dashboard travels back into the session.

## TLDR
## User Stories

- The user sees the question a parked cloud session is waiting on in the dashboard, without watching claude.ai.
- The user answers it in the dashboard, and the answer is typed back into the claude.ai session.
- The user follows the cloud session's transcript from the dashboard.

## Flows

- A cloud agent hands off and ends, so when its session later asks something, nothing streams back and the question strands on claude.ai; the extension reads the session page the user is already signed into and carries the question — plus a mirror of the transcript — to the daemon.
- Two halves with a strict trust line: the page script reads claude.ai and types into it but never holds a secret; the background worker holds the bridge token and is the only part that talks to the daemon — which refuses cross-origin calls on purpose, so no website the user visits can reach the dashboard.
- Two halves with a strict trust line: the page script reads claude.ai and types into it but never holds a secret; the background worker holds the bridge token and is the only part that talks to the daemon.
- Answers go the long way round: dashboard pick → daemon queue → worker → typed into the session's composer and submitted; the extension can only ever type a label the session itself offered, and the pick was confirmed in the dashboard first.
- It keeps one pinned background tab per session the daemon watches, so the bridge works with nobody looking at claude.ai — closing tabs when watching stops, and never reopening one the user closed.
- Reading is driven by page changes with a slow heartbeat backstop (it lives in background tabs), and every stage reports its status — on the page's panel and in the settings page's connection test — so a silent misconfiguration is visible.
- The extension and the daemon insist on matching versions: every call states the manifest version, and a daemon expecting another blocks it with an error naming both and the update path, because a version-skewed pair half-works in ways that read as bugs.
- Reading is driven by page changes with a slow heartbeat backstop, and every stage reports its status — on the page's panel and in the settings page's connection test — so a silent misconfiguration is visible.
- The extension and the daemon insist on matching versions: every call states the extension's version, and a daemon expecting another blocks it with an error naming both and the update path.

## Rationales

- **The trust line.** The daemon refuses cross-origin calls on purpose, so no website the user visits can reach the dashboard; only the background worker is exempt, and nothing sharing a tab with claude.ai should ever hold the secret — which is why the token and every daemon call live in the worker.
- **Built for background tabs.** The bridge lives in pinned tabs nobody looks at, where the browser throttles timers — so reading rides on page changes and the heartbeat is only a backstop.
- **Versions must match.** A version-skewed extension–daemon pair half-works in ways that read as bugs, so the daemon blocks it loudly instead of degrading.

## Before modifying/creating SPEC.md files

Expand Down
13 changes: 9 additions & 4 deletions packages/chrome-extension/background.SPEC.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
The extension's daemon half: the only part holding the bridge token and talking to the local dashboard — it forwards what the page half finds, delivers the dashboard's answers into the right tab, and keeps a pinned tab open per watched session.

## TLDR
## Flows

- The token and every daemon call live here: the page half shares a tab with claude.ai and must never see the secret, and the daemon refuses cross-origin requests on purpose — only this half is exempt.
- Questions forward with a dedupe: the page re-reports on every change, and an unchanged question for the same session costs nothing.
- Answers travel back: queued picks are fetched on a fast beat (a person is watching a spinner), handed to the page in that session's tab to type, and the outcome reported — typing before reporting, so a pick is never marked sent that a dying tab never typed; failed deliveries and reports are retried, not dropped.
- One pinned, inactive tab opens per session the daemon says to watch — the extension cannot know on its own that a cloud agent started; stale ones close, and a tab the user closed is never reopened.
- Answers travel back: queued picks are fetched on a fast beat, handed to the page in that session's tab to type, and the outcome reported — typing before reporting, so a pick is never marked sent that a dying tab never typed; failed deliveries and reports are retried, not dropped.
- One pinned, inactive tab opens per session the daemon says to watch; stale ones close, and a tab the user closed is never reopened.
- Every sweep records why it did or didn't act, so "tabs are not opening" is answerable from the options page.
- Every daemon call states this extension's version; a daemon expecting another refuses outright with both versions named, so a stale install blocks loudly instead of half-working.

## Rationales

- **The token and every daemon call live here.** The page half shares a tab with claude.ai and must never see the secret, and the daemon refuses cross-origin requests on purpose — only this half is exempt.
- **Answers are fetched on a fast beat.** A person is sitting on the other end of a delivery, watching a spinner that says the pick is on its way.
- **The daemon names the sessions to watch.** The extension cannot know on its own that a cloud agent started — it only sees pages it is already injected into.

## Before modifying/creating SPEC.md files

You must always read and respect https://raw.githubusercontent.com/brillout/sdd/refs/heads/main/sdd.md
9 changes: 7 additions & 2 deletions packages/chrome-extension/content.SPEC.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
The extension's page half: injected into claude.ai session pages, it finds the question a parked session is waiting on, mirrors the transcript, types a delivered answer into the composer, and shows a status panel — never holding the token or talking to the daemon itself.

## TLDR
## Flows

- The question is the JSON options block our agents emit, brace-matched out of surrounding prose wherever it hides — code elements, shadow roots, split across highlighter spans — and the page's rendered copy of our own protocol is a decoy three ways (#1568): nothing inside the transcript's opening message counts (that is the prompt rendering, examples included), a placeholder-shaped title is the spec talking even when punctuation joins the placeholders, and the protocol's two literal examples are matched verbatim; the last real question among what survives wins.
- The transcript mirrors as per-message blocks when the page marks them, else as the visible conversation text from the newest end (application chrome and our own panel stripped); only what changed since the last look is sent.
- Delivering an answer is the one action taken: the pick is typed into the composer and submitted, after patiently waiting for a slow page to render the composer; only the top frame types, so nothing submits twice — and only labels the session itself offered can ever be typed.
- It re-reads on page mutation with a slow heartbeat backstop (built to run in background tabs), and its collapsible panel reports every stage's status — found, sent, delivered, and why not — because silent failure was the recurring failure.
- It re-reads on page mutation with a slow heartbeat backstop, and its collapsible panel reports every stage's status — found, sent, delivered, and why not.

## Rationales

- **Built to run in background tabs.** The tabs the bridge lives in are pinned and hidden, where the browser throttles timers — and the session's own stream changes the page whenever anything happens, so reacting to page mutations is immediate and the heartbeat is only a backstop.
- **Every stage reports.** A stage that fails silently is indistinguishable from a bridge with nothing to do.

## Before modifying/creating SPEC.md files

Expand Down
2 changes: 1 addition & 1 deletion packages/chrome-extension/options.SPEC.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The settings page: the daemon address, the bridge token, and the tab-opening switch live in extension storage — never in the page — and saving immediately proves the connection instead of just storing it.

## TLDR
## Flows

- The test names the exact failure: Chrome not actually granting site access (declared is not granted, and without it the daemon sees nothing), daemon unreachable, token rejected, a version the daemon refuses (its answer, naming both versions and the way out, is shown verbatim), bridge switched off, or a dashboard too old to have a bridge — whose look-alike success page is not accepted as connected.
- Success also says how many cloud sessions the daemon is watching, so "connected but nothing happens" answers itself.
Expand Down
9 changes: 8 additions & 1 deletion packages/the-framework.ai/SPEC.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
The product's marketing website, the-framework.ai — it pitches The Framework and funnels visitors into trying it.

## TLDR
## User Stories

- A visitor reads the pitch and copies one terminal command to try The Framework.
- A visitor picks their package manager once and every command on the site follows, this visit and the next.
- A visitor landing on the go-to-dashboard page learns the dashboard runs on their own machine and how to launch it.
- Someone writing about The Framework downloads logos, naming rules, and the banner from the press page.

## Flows

- One long landing page carries the whole pitch: stop babysitting AI, make the important decisions, let AI do the rest.
- The main call to action everywhere is a copy-pasteable terminal command that runs The Framework; visitors pick their package manager once and every command site-wide shows in that flavor, remembered across visits.
Expand Down
2 changes: 1 addition & 1 deletion packages/the-framework.ai/pages/SPEC.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The website's pages — the landing page plus three small side pages — and the head/settings they all share.

## TLDR
## Flows

- / is the landing page carrying the whole pitch; it also hosts the shared building blocks the side pages reuse.
- /press offers brand material, /go-to-dashboard explains how to open the locally-running dashboard, and /banner exists only to be screenshotted into the social-preview image.
Expand Down
2 changes: 1 addition & 1 deletion packages/the-framework.ai/pages/index/AutonomousAi.SPEC.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
The "Autonomous AI" section: two cards listing what AI handles autonomously — product management and coding — with reassurances that agents still ask before non-obvious decisions and that you pick the autonomy level.
The "Autonomous AI" section: two cards listing what AI does autonomously — product management and coding — with reassurances that agents still ask before non-obvious decisions and that you pick the autonomy level.

## Before modifying/creating SPEC.md files

Expand Down
2 changes: 1 addition & 1 deletion packages/the-framework.ai/pages/index/Hero.SPEC.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The opening screen: the promise (strike through "Babysit AI", announce "Autonomous AI" — make the important decisions, let AI do the rest) plus the fastest possible path to trying the product.

## TLDR
## Flows

- Leads with the trust badges (100% open source, free, local), the headline, and the tagline.
- A one-shot "try" command takes center stage, with a smaller install command as alternative; one click copies either.
Expand Down
10 changes: 8 additions & 2 deletions packages/the-framework.ai/pages/index/SPEC.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
The landing page — the product pitch told top to bottom — plus the shared building blocks the other pages borrow.

## TLDR
## User Stories

- The pitch order: the promise and a try-it-now command (hero), the babysitting problems The Framework solves, what AI handles autonomously, how it works (the two building blocks: enhanced system prompt and queues, powered by open-source prompts), the feature list, why the framework is yours (flexible, local, open source), and a closing invitation to the community.
- A visitor scrolls the pitch from promise to community invitation and copies a try-it-now command on the way.
- A visitor shares a link that opens the page at the exact section they were reading.
- A visitor picks their package manager once and every command follows, on this page and every other.

## Flows

- The pitch order: the promise and a try-it-now command (hero), the babysitting problems The Framework solves, what AI does autonomously, how it works (the two building blocks: enhanced system prompt and queues, powered by open-source prompts), the feature list, why the framework is yours (flexible, local, open source), and a closing invitation to the community.
- A sticky section menu follows the reader and keeps the page address in sync with the visible section, so any section can be shared as a link.
- Every command appears in the visitor's chosen package manager, copies with one click, and the choice is remembered across pages and visits.
- This directory doubles as the site's component library: the other pages reuse its navigation bar, footer, styling, copy-to-clipboard behavior, and package-manager machinery.
Expand Down
Loading
Loading