Xinmin Zeng 2a97ec3e58
docs: turn README into an index and move reference detail to docs/guide (#8113)
* docs: turn README into an index and move reference detail to docs/guide

The README had grown to 393 KB because every change appended its notes there. The text moves verbatim into 18 topic guides under docs/guide/; only headings are re-leveled and relative links re-pointed. The README keeps the introduction, a quick start and a guide index. Contributor test notes move to CONTRIBUTING.md.

* docs: send user docs to topic guides and budget the root README

The rule 'update README.md for user-facing changes' is what grew the README. Guidance now points to docs/guide/, and check_agent_guidance.py fails when the root README exceeds 16 KiB (AG003).

* chore: remove unreferenced screenshots and finished plan notes

pr-build/ holds two PR screenshots (3 MB) from #1986. plans/ holds the plan for the merged #4049. docs/SKILL_NAME_CONFLICT_FIX.md is a February change note. Nothing references them.

* docs: route always-loaded AGENTS.md files to scoped guides

* docs(agents): cut scoped guides to scope, verify, traps, decisions

Each AGENTS.md keeps four kinds of content: the scope of the directory, the
verification commands, traps a local test run does not show, and decisions the
code cannot state. Values, field lists, function inventories, test names, issue
numbers and history are deleted, because the code, the tests and git state them.

Search and fetch providers share one community guide. Four guides with no
remaining content are removed. The size check now allows 6 KiB per file (hard
limit 8 KiB) and 24 KiB per chain (hard limit 32 KiB).

* style: format frontend guide table and guidance test imports

---------

Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-11-11 13:26:17 +08:00

83 lines
4.0 KiB
Markdown

# Script workflow extension (`examples/deerflow-extension-workflows/`)
An installable extension that runs a generated script as a workflow over public
AgentRuns, with human approval, crash recovery and an optional PostgreSQL cluster
mode. The workflow logic stays in this package.
## Verify
```bash
cd backend
python -m pytest tests/test_workflow_plugin.py tests/test_workflow_recovery.py -q
make test-blocking-io
```
Then run `verify_browser.mjs`. The cluster tests need
`DEERFLOW_TEST_WORKFLOW_POSTGRES`, and the deployed acceptance test needs
`DEERFLOW_WORKFLOW_ACCEPTANCE=1` with Docker. The browser fixture and the
acceptance entry point are test-only and must never become a deployed
authentication or admission bypass.
## Boundaries
- **Import only `deerflow_extension_api`, the standard library and the declared
QuickJS dependency.** Host `app.*` and `deerflow.*` modules are private.
- **The generated script runs only in the worker's isolated JavaScript context.**
Never pass it a host callable, a capability handle, a credential or the
environment. `Date` and random values are unavailable there.
- **The parent kills and reaps the worker**, and every IPC, stored and public
payload is bounded.
- **Never serialize a capability handle**, and never rebuild authority from a
stored user ID. Recovery binds a fresh authenticated session.
- **Owner scope applies to every public read and mutation.**
## Admission, cancellation and results
- **Persist the child thread, input message, attempt and idempotency identity
before admission.**
- **A timeout or an unknown admission outcome is reconciled, never retried.** An admission that was provably rejected
releases its capacity; an unknown one keeps it.
- **Workflow cancel is a signal to the supervisor.** Do not cancel the admission
task itself, which would lose a child that already exists.
- **Keep admission uncertainty apart from an observation timeout after
admission.** A known run is interrupted and observed.
- **Agent success is never human approval.** A human decision is bound to the
output hash, the step and attempt, and the authenticated session.
- **A thread's latest state is not an immutable run output.** Check message and
run attribution, interrupts and pending human input before you copy an output.
Anchor a result on the visible human input.
- **Keep the supervisor outcome private until child tasks and fenced cleanup
finish.** Publishing the terminal status early retires the PostgreSQL lease
before the reservations are released.
- **This extension gives no hard currency limit and does not freeze external
state.** Do not claim either.
## Recovery
- **Persist the bridge intent before a host effect, and the response before it is
delivered to the worker.** Replay reuses committed outputs and decisions.
- **Replay after a restart needs an authenticated recovery action.** Legacy
records are for inspection only.
- **A captured file is read by its stored step and version.** Do not overwrite it
from a mutable source.
- **Compatibility checks include the worker source, the supervisor source and
the engine version.** `constants.py` holds the registration and lease
namespace as one declaration and is part of that signature.
- **A stored `cancelling` state is never replayed.** An expired one is
recoverable for cancel cleanup only.
## Storage modes
- **SQLite mode holds the process lock for the life of the service.** Do not
recover live records while another Gateway owns the file.
- **PostgreSQL mode shares one database and schema with the host.** Every
supervisor write, file capture, child admission and child cancellation is
fenced by a lease epoch on the database clock. Host admission and cancel lock
the lease row inside their transaction; a preflight check is not a
replacement.
- **Lease loss kills only the local worker.** Do not clean up children that a
successor now owns. A takeover needs a fresh session and a matching runtime
and configuration.
- **Drain a SQLite write through repeated cancellation** before you release the
write lock.