@temporal-architect/claude-plugin 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +38 -0
- package/package.json +37 -0
- package/skills/MANIFEST.json +373 -0
- package/skills/MANIFEST.md +121 -0
- package/skills/temporal-architect/SKILL.md +99 -0
- package/skills/temporal-architect/reference/decomposition.md +78 -0
- package/skills/temporal-architect-author-go/README.md +16 -0
- package/skills/temporal-architect-author-go/SKILL.md +191 -0
- package/skills/temporal-architect-author-go/SUBAGENT_ADOPTION.md +161 -0
- package/skills/temporal-architect-author-go/reference/activity-call.md +73 -0
- package/skills/temporal-architect-author-go/reference/activity-def.md +54 -0
- package/skills/temporal-architect-author-go/reference/assignment.md +36 -0
- package/skills/temporal-architect-author-go/reference/await-all.md +104 -0
- package/skills/temporal-architect-author-go/reference/await-one.md +193 -0
- package/skills/temporal-architect-author-go/reference/await-timer.md +35 -0
- package/skills/temporal-architect-author-go/reference/close.md +71 -0
- package/skills/temporal-architect-author-go/reference/composite-patterns.md +176 -0
- package/skills/temporal-architect-author-go/reference/condition.md +56 -0
- package/skills/temporal-architect-author-go/reference/control-flow.md +151 -0
- package/skills/temporal-architect-author-go/reference/dependency-resolution.md +29 -0
- package/skills/temporal-architect-author-go/reference/detach.md +52 -0
- package/skills/temporal-architect-author-go/reference/heartbeat.md +84 -0
- package/skills/temporal-architect-author-go/reference/nexus-service-def.md +73 -0
- package/skills/temporal-architect-author-go/reference/nexus.md +35 -0
- package/skills/temporal-architect-author-go/reference/options.md +138 -0
- package/skills/temporal-architect-author-go/reference/promise.md +73 -0
- package/skills/temporal-architect-author-go/reference/proto-driven.md +197 -0
- package/skills/temporal-architect-author-go/reference/query-handler.md +34 -0
- package/skills/temporal-architect-author-go/reference/signal-handler.md +73 -0
- package/skills/temporal-architect-author-go/reference/three-layer-testing.md +173 -0
- package/skills/temporal-architect-author-go/reference/types.md +72 -0
- package/skills/temporal-architect-author-go/reference/update-handler.md +64 -0
- package/skills/temporal-architect-author-go/reference/worker.md +215 -0
- package/skills/temporal-architect-author-go/reference/workflow-call.md +37 -0
- package/skills/temporal-architect-author-go/reference/workflow-def.md +45 -0
- package/skills/temporal-architect-author-infra/README.md +16 -0
- package/skills/temporal-architect-author-infra/SKILL.md +132 -0
- package/skills/temporal-architect-author-infra/reference/tcld.md +112 -0
- package/skills/temporal-architect-author-infra/reference/terraform.md +125 -0
- package/skills/temporal-architect-design/README.md +16 -0
- package/skills/temporal-architect-design/SKILL.md +224 -0
- package/skills/temporal-architect-design/reference/LANGUAGE.md +5 -0
- package/skills/temporal-architect-design/reference/anti-patterns.md +332 -0
- package/skills/temporal-architect-design/reference/common-errors.md +88 -0
- package/skills/temporal-architect-design/reference/core-principles.md +52 -0
- package/skills/temporal-architect-design/reference/design-checklist.md +59 -0
- package/skills/temporal-architect-design/reference/namespaces.md +84 -0
- package/skills/temporal-architect-design/reference/notation-examples.md +304 -0
- package/skills/temporal-architect-design/reference/notation-reference.md +70 -0
- package/skills/temporal-architect-design/reference/primitives-reference.md +65 -0
- package/skills/temporal-architect-design/reference/project-discovery-subagent.md +80 -0
- package/skills/temporal-architect-design/reference/reverse-engineering.md +53 -0
- package/skills/temporal-architect-design/reference/twf-conventions.md +43 -0
- package/skills/temporal-architect-design/reference/workflow-boundaries.md +43 -0
- package/skills/temporal-architect-design/topics/activities-advanced.md +358 -0
- package/skills/temporal-architect-design/topics/activities-advanced.twf +107 -0
- package/skills/temporal-architect-design/topics/child-workflows.md +347 -0
- package/skills/temporal-architect-design/topics/child-workflows.twf +171 -0
- package/skills/temporal-architect-design/topics/long-running.md +230 -0
- package/skills/temporal-architect-design/topics/long-running.twf +100 -0
- package/skills/temporal-architect-design/topics/nexus.md +248 -0
- package/skills/temporal-architect-design/topics/nexus.twf +148 -0
- package/skills/temporal-architect-design/topics/patterns.md +469 -0
- package/skills/temporal-architect-design/topics/patterns.twf +346 -0
- package/skills/temporal-architect-design/topics/promises-conditions.md +179 -0
- package/skills/temporal-architect-design/topics/promises-conditions.twf +213 -0
- package/skills/temporal-architect-design/topics/signals-queries-updates.md +319 -0
- package/skills/temporal-architect-design/topics/signals-queries-updates.twf +234 -0
- package/skills/temporal-architect-design/topics/task-queues.md +205 -0
- package/skills/temporal-architect-design/topics/task-queues.twf +184 -0
- package/skills/temporal-architect-design/topics/testing.md +437 -0
- package/skills/temporal-architect-design/topics/testing.twf +177 -0
- package/skills/temporal-architect-design/topics/timers-scheduling.md +131 -0
- package/skills/temporal-architect-design/topics/timers-scheduling.twf +129 -0
- package/skills/temporal-architect-design/topics/versioning.md +434 -0
- package/skills/temporal-architect-design/topics/versioning.twf +174 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Temporal Cloud + Terraform (`temporalio/temporalcloud`)
|
|
2
|
+
|
|
3
|
+
Provision Temporal Cloud control-plane resources with the official Terraform provider. This is the target when the repo already has `*.tf` referencing `temporalio/temporalcloud`, or when the user chooses Temporal Cloud for greenfield.
|
|
4
|
+
|
|
5
|
+
## Provider Setup
|
|
6
|
+
|
|
7
|
+
```hcl
|
|
8
|
+
terraform {
|
|
9
|
+
required_providers {
|
|
10
|
+
temporalcloud = {
|
|
11
|
+
source = "temporalio/temporalcloud"
|
|
12
|
+
version = ">= 0.0.6"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
provider "temporalcloud" {
|
|
18
|
+
# api_key = "..." # prefer the env var below over inlining a secret
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Authenticate with a Temporal Cloud API key via the environment — never commit it:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
export TEMPORAL_CLOUD_API_KEY=<your-secret-key>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## `temporalcloud_namespace`
|
|
29
|
+
|
|
30
|
+
Maps from a `.twf` `namespace` block.
|
|
31
|
+
|
|
32
|
+
```hcl
|
|
33
|
+
resource "temporalcloud_namespace" "orders" {
|
|
34
|
+
name = "orders"
|
|
35
|
+
regions = ["aws-us-east-1"] # cloud-prefixed; 1 region, or 2 for HA replication
|
|
36
|
+
retention_days = 14
|
|
37
|
+
|
|
38
|
+
# Auth: choose ONE model.
|
|
39
|
+
api_key_auth = true
|
|
40
|
+
# accepted_client_ca = base64encode(file("${path.module}/ca.pem")) # mTLS alternative
|
|
41
|
+
|
|
42
|
+
namespace_lifecycle = {
|
|
43
|
+
enable_delete_protection = true # blocks accidental destroy; flip to false before destroying
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Key attributes:
|
|
49
|
+
|
|
50
|
+
| Attribute | Notes |
|
|
51
|
+
|-----------|-------|
|
|
52
|
+
| `name` | Must start/end alphanumeric, hyphens allowed. The `.twf` namespace name. |
|
|
53
|
+
| `regions` | Cloud-prefixed (`aws-us-east-1`, not `us-east-1`). One region, or two for an HA namespace. **Changing/adding/removing regions on an existing namespace is not supported** — the provider errors. |
|
|
54
|
+
| `retention_days` | Workflow history retention. A deliberate cost/compliance choice — ask the user. |
|
|
55
|
+
| `api_key_auth` vs `accepted_client_ca` | API-key auth or mTLS client CA. Pick the model the workers will use; this must match `author-go`'s client config. |
|
|
56
|
+
| `namespace_lifecycle.enable_delete_protection` | Recommend `true` for anything real. |
|
|
57
|
+
|
|
58
|
+
## `temporalcloud_namespace_search_attribute`
|
|
59
|
+
|
|
60
|
+
One resource per custom search attribute. **Not yet modeled in `.twf`** — ask the user for the name and type (see SKILL.md → Not-Yet-Modeled Intent).
|
|
61
|
+
|
|
62
|
+
```hcl
|
|
63
|
+
resource "temporalcloud_namespace_search_attribute" "order_status" {
|
|
64
|
+
namespace_id = temporalcloud_namespace.orders.id
|
|
65
|
+
name = "OrderStatus"
|
|
66
|
+
type = "Keyword" # one of: Bool, Datetime, Double, Int, Keyword, KeywordList, Text (case-insensitive)
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## `temporalcloud_nexus_endpoint`
|
|
71
|
+
|
|
72
|
+
Maps from a `.twf` `nexus endpoint` block. The endpoint's `worker_target` is the `.twf` endpoint's target namespace + `task_queue`; `allowed_caller_namespaces` is the access policy (**not yet in `.twf`** — ask the user which caller namespaces to trust; do not default to allow-all).
|
|
73
|
+
|
|
74
|
+
```hcl
|
|
75
|
+
resource "temporalcloud_nexus_endpoint" "payments_endpoint" {
|
|
76
|
+
name = "payments-endpoint"
|
|
77
|
+
description = "Service: PaymentsService; Operations: ProcessPayment, GetPaymentStatus"
|
|
78
|
+
|
|
79
|
+
worker_target = {
|
|
80
|
+
namespace_id = temporalcloud_namespace.payments.id # the .twf endpoint's target namespace
|
|
81
|
+
task_queue = "payments" # the .twf worker_target task_queue
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
allowed_caller_namespaces = [
|
|
85
|
+
temporalcloud_namespace.orders.id, # caller namespace(s) — the access policy
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Notes:
|
|
91
|
+
- `name` must match `^[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9]$` and is the identifier caller workflow code uses to invoke the endpoint — it must match the endpoint name in the `.twf` / `author-go` output.
|
|
92
|
+
- Only a single `worker_target` is supported per endpoint.
|
|
93
|
+
- `allowed_caller_namespaces` is the runtime access control: only listed namespaces may invoke the endpoint.
|
|
94
|
+
|
|
95
|
+
## Import + Drift Workflow (adopting existing infra)
|
|
96
|
+
|
|
97
|
+
When the resource already exists in Temporal Cloud, **import it before managing** — otherwise Terraform plans a create and you get a duplicate or an error.
|
|
98
|
+
|
|
99
|
+
1. Write an empty (or matching) resource block as the import target.
|
|
100
|
+
2. Import using the resource's ID:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# Namespace — ID is namespaceid.acctid (or just the namespace id, per UI)
|
|
104
|
+
terraform import temporalcloud_namespace.orders <namespace-id>
|
|
105
|
+
|
|
106
|
+
# Search attribute — ID is namespaceid.acctid/attrName
|
|
107
|
+
terraform import temporalcloud_namespace_search_attribute.order_status <namespace-id>/OrderStatus
|
|
108
|
+
|
|
109
|
+
# Nexus endpoint — ID from `tcld nexus endpoint list`
|
|
110
|
+
terraform import temporalcloud_nexus_endpoint.payments_endpoint <endpoint-id>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
3. `terraform plan` — reconcile the block to match reality until the plan is clean (no changes). A non-empty plan after import means your HCL diverges from the live resource; fix the HCL, don't apply blindly.
|
|
114
|
+
|
|
115
|
+
**Drift discipline:** once imported/managed, never edit the resource in the console or via `tcld` — the next `terraform plan` will try to revert it. Terraform is the single owner. Run `terraform plan` in CI to detect drift early.
|
|
116
|
+
|
|
117
|
+
## Verify
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
terraform init
|
|
121
|
+
terraform plan # review the diff; an unexpected "create" on a resource that should exist means a missing import
|
|
122
|
+
terraform apply
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Confirm the provisioned task queue names match what `author-go`'s workers register on — a mismatch means Nexus tasks route nowhere.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Skill: Temporal Architect — System Design
|
|
2
|
+
|
|
3
|
+
**Goal:** Guide an AI to design well-structured Temporal systems using `.twf` — making sound architectural decisions about workflow boundaries, activity decomposition, and primitive selection.
|
|
4
|
+
|
|
5
|
+
**Primary focus:** Judgment. The hard part is not syntax — it's knowing *when* to use each primitive, *where* to draw boundaries, and *how* to model async behavior clearly. This skill teaches those decisions.
|
|
6
|
+
|
|
7
|
+
**Scope:**
|
|
8
|
+
- Produces: a validated `.twf` design file
|
|
9
|
+
- Consumes: a user's description of the system or process to model
|
|
10
|
+
- Does not: generate Go code (that's `author-go`), implement the parser, or modify the DSL
|
|
11
|
+
|
|
12
|
+
**Authoritative references:**
|
|
13
|
+
- `tools/spec/sections/` — DSL ground truth; consult for any syntax or construct question (also `twf spec` / `twf spec <slug>`)
|
|
14
|
+
- Temporal docs MCP server — consult for Temporal primitive semantics before making design decisions
|
|
15
|
+
|
|
16
|
+
**Entry point:** `SKILL.md` → `reference/` on demand → `topics/` for worked examples
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: temporal-architect-design
|
|
3
|
+
description: Design Temporal systems — workflows, activities, workers, namespaces, and Nexus — with proper determinism, idempotency, and decomposition in `.twf`. Use when designing or reviewing Temporal architecture, planning workflow/activity boundaries, or decomposing a system into Temporal primitives.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Temporal Architect: System Design
|
|
7
|
+
|
|
8
|
+
Design entire Temporal systems using `.twf` (Temporal Workflow Format) — capturing system topology, workflow structure, activity boundaries, and Temporal primitives as a parseable source of truth. Always produce `.twf` files as deliverables, never SDK code.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Design Flow
|
|
13
|
+
|
|
14
|
+
Core loop: **orient → write TWF → `twf check` → fix/consult → design review → repeat**. Parser errors are design feedback — validate early and often. But a clean `twf check` is a *grammar gate*, not a finished design: it never routes straight to done (see [Design Review](#design-review)).
|
|
15
|
+
|
|
16
|
+
**Write before you read the reference docs.** Draft TWF from the workflow description even if you're unsure — use `twf check --lenient` while iterating on incomplete designs — it still reports every error, it just exits 0 instead of failing the gate. Consult `notation-reference.md` and the other references only to fix specific errors, not to prepare. **This does not apply to prior project artifacts** (existing `.twf`, `DESIGN.md`): those are requirements — read them first (see [Orient](#orient)).
|
|
17
|
+
|
|
18
|
+
### Orient
|
|
19
|
+
|
|
20
|
+
Before drafting, glance for prior work — a quick discovery step, not a research phase:
|
|
21
|
+
|
|
22
|
+
- existing `.twf` files in the project,
|
|
23
|
+
- prior design docs (`DESIGN.md`, `docs/`-style notes, `archive*/` directories).
|
|
24
|
+
|
|
25
|
+
If found, read them **as requirements** and enter [Revising an Existing Design](#revising-an-existing-design) rather than drafting from scratch — drafting on top of validated prior work re-derives (and silently diverges from) boundaries someone already debated. When the task is migrating an existing orchestration (Claude-Code → Temporal, cron → Temporal, etc.), the prior artifacts *are* the requirements; discovering and reading them is the first step, not a detour.
|
|
26
|
+
|
|
27
|
+
**When the source of truth is existing code** (an already-running Temporal app, no design doc — the dominant adoption path), the `.twf` is *recovered from the implementation*, not drafted. This is a distinct, **parallel** path — do not improvise it inline, and do not let it slow the greenfield loop. Trigger it deliberately on a **bounded slice** (one domain at a time, never the whole repo reflexively), dispatch the [project-discovery subagent](./reference/project-discovery-subagent.md) to scan in isolation, and follow [reverse-engineering.md](./reference/reverse-engineering.md) for the mechanics. The reverse path rejoins the core loop at [Design Review](#design-review).
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
┌────────────┐
|
|
31
|
+
│ Write/Edit │◄────────────────────────┐
|
|
32
|
+
│ .twf file │ │
|
|
33
|
+
└─────┬──────┘ │
|
|
34
|
+
▼ │
|
|
35
|
+
┌────────────┐ │
|
|
36
|
+
│ twf check │ │
|
|
37
|
+
└─────┬──────┘ │
|
|
38
|
+
▼ │
|
|
39
|
+
┌─────────┐ Yes ┌─────────────┐ │
|
|
40
|
+
│ Error? │────────►│ Can fix │ │
|
|
41
|
+
└────┬────┘ │ confidently?│ │
|
|
42
|
+
│No └──┬───────┬──┘ │
|
|
43
|
+
│ Yes │ │No │
|
|
44
|
+
│ │ ▼ │
|
|
45
|
+
│ │ ┌─────────┐ │
|
|
46
|
+
│ │ │ Consult │ │
|
|
47
|
+
│ │ │ user │ │
|
|
48
|
+
│ │ └────┬────┘ │
|
|
49
|
+
│ └───────┴──────┤
|
|
50
|
+
▼ │
|
|
51
|
+
┌───────────────┐ │
|
|
52
|
+
│ Design Review │ (fresh-eyes rubric) │
|
|
53
|
+
└───────┬───────┘ │
|
|
54
|
+
▼ │
|
|
55
|
+
┌─────────┐ Yes (revise) │
|
|
56
|
+
│ Issues? │─────────────────────────┘
|
|
57
|
+
└────┬────┘
|
|
58
|
+
│No
|
|
59
|
+
▼
|
|
60
|
+
Done
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Worked Example
|
|
64
|
+
|
|
65
|
+
**Draft** — write from the description, don't worry about completeness:
|
|
66
|
+
|
|
67
|
+
```twf
|
|
68
|
+
workflow ProcessOrder(order: Order) -> (OrderResult):
|
|
69
|
+
activity ValidateOrder(order) -> validated
|
|
70
|
+
activity ChargePayment(order.payment) -> payment
|
|
71
|
+
activity ShipOrder(order, payment) -> shipment
|
|
72
|
+
close complete(OrderResult{shipment})
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Iteration 1** — `twf check` finds errors:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
resolve error at 2:5: undefined activity "ValidateOrder"
|
|
79
|
+
resolve error at 3:5: undefined activity "ChargePayment"
|
|
80
|
+
resolve error at 4:5: undefined activity "ShipOrder"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Fix — add the missing definitions. `twf check` → `✓ OK`
|
|
84
|
+
|
|
85
|
+
**Iteration 2** — design review. Shipping involves creating a shipment, waiting for carrier pickup, and tracking — multiple steps with independent retry. Consult [workflow-boundaries.md](./reference/workflow-boundaries.md): multi-step orchestration with its own lifecycle → child workflow.
|
|
86
|
+
|
|
87
|
+
Revise — extract `ShipOrder` as a child workflow, and make the behavior over time and at scale explicit. `twf check` validates structure but says nothing about timeouts, retries, or history growth — those are design decisions you must add:
|
|
88
|
+
|
|
89
|
+
```twf
|
|
90
|
+
workflow ProcessOrder(order: Order) -> (OrderResult):
|
|
91
|
+
activity ValidateOrder(order) -> validated
|
|
92
|
+
activity ChargePayment(order.payment) -> payment
|
|
93
|
+
options:
|
|
94
|
+
start_to_close_timeout: 30s # bound the external charge call
|
|
95
|
+
retry_policy:
|
|
96
|
+
maximum_attempts: 3 # payment provider can be flaky
|
|
97
|
+
workflow ShipOrder(order, payment) -> shipment
|
|
98
|
+
close complete(OrderResult{shipment})
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`twf check` → `✓ OK`. Structurally sound — now run the [Design Review](#design-review) before presenting.
|
|
102
|
+
|
|
103
|
+
**Long-running variant** — when a workflow loops over a large bound (or accumulates chunky per-iteration history), it must reach `close continue_as_new(...)` even though the loop is finite. A bound alone does not make history safe:
|
|
104
|
+
|
|
105
|
+
```twf
|
|
106
|
+
workflow ReindexCatalog(cursor: Cursor):
|
|
107
|
+
pageCount = 0
|
|
108
|
+
for:
|
|
109
|
+
activity FetchPage(cursor) -> page
|
|
110
|
+
activity IndexItems(page.items)
|
|
111
|
+
cursor = page.next
|
|
112
|
+
pageCount = pageCount + 1
|
|
113
|
+
if (cursor == null):
|
|
114
|
+
close complete
|
|
115
|
+
# History grows per page — reset it before it gets large.
|
|
116
|
+
if (pageCount >= 500):
|
|
117
|
+
close continue_as_new(cursor)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Design Review
|
|
121
|
+
|
|
122
|
+
A clean `twf check` (and, when it exists, `twf lint`) does **not** mean the design is correct. Idempotency of side effects, concurrent-write races, and cross-file payload data flow are invisible to the tooling and remain review concerns. Before presenting, do one **fresh-eyes pass**: re-read the finished design as if reviewing someone else's PR — set the prose/intent aside, or dispatch a reviewer that sees only the `.twf` artifacts. Self-review with the authoring mindset reproduces the author's blind spots; the value is in the *independence* of the second look, not its existence.
|
|
123
|
+
|
|
124
|
+
Grade against this rubric:
|
|
125
|
+
|
|
126
|
+
- **Call-site integrity** — every `activity` / `workflow` / `nexus` definition has at least one *structured* call site. A bare expression like `x = ActName(args)` parses as `raw` text and is silently **not** wired up — these orphans hide behind a clean `twf check`.
|
|
127
|
+
- **Reachability / dead code** — every workflow is reachable from a declared entry point via a call or Nexus op. Call out leftover/dead workflows; don't assume they're live.
|
|
128
|
+
- **Anti-pattern re-check** — walk the finished design against every entry in [anti-patterns.md](./reference/anti-patterns.md). Wrapper workflows, monoliths, and unbounded/bounded-but-large history are exactly what get copied in uncritically.
|
|
129
|
+
- **Idempotency** — each non-idempotent-by-nature activity states its idempotency strategy and key derivation (e.g. "workflow ID + activity name"). No tool validates this.
|
|
130
|
+
- **Concurrent writes to shared state** — does any parallel fan-out (`await all`, `for` + promises) have branches that write the same external blob/record? If so, state the isolation/keying assumption. TWF can't express it, so no tool can catch it — human-review-only.
|
|
131
|
+
- **Runtime / cost / lifecycle** — timeouts and retries set where failure can happen; history growth bounded (`continue_as_new` where needed); large payloads handled (see [anti-patterns.md](./reference/anti-patterns.md#large-payloads-in-workflow-state)).
|
|
132
|
+
|
|
133
|
+
### Revising an Existing Design
|
|
134
|
+
|
|
135
|
+
This is also the entry point when [Orient](#orient) surfaces prior work. Treat prior artifacts as **requirements**, not reference material. Run `twf symbols` to understand current structure, make edits, then re-enter the core loop (`twf check` → fix → [Design Review](#design-review) → repeat). Treat user feedback as new requirements — ask clarifying questions before editing if the feedback is ambiguous.
|
|
136
|
+
|
|
137
|
+
### When to Consult the User
|
|
138
|
+
|
|
139
|
+
**Fix yourself:** clear syntax mistakes, unambiguous errors (undefined → add definition), pattern exists in docs.
|
|
140
|
+
|
|
141
|
+
**Ask the user:** multiple valid approaches, requirements gap, unclear architectural choice, workaround feels wrong.
|
|
142
|
+
|
|
143
|
+
**Cost of asking < Cost of wrong design.**
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## `twf` CLI
|
|
148
|
+
|
|
149
|
+
**Run `twf check` after every `.twf` edit.** Fix all errors before presenting to user.
|
|
150
|
+
|
|
151
|
+
For the authoritative flag set on any command, run `twf help` or
|
|
152
|
+
`twf <command> --help` — that help is generated from the binary and never
|
|
153
|
+
drifts. The table below is the *when/why*, not the flag reference:
|
|
154
|
+
|
|
155
|
+
| Command | Purpose |
|
|
156
|
+
|---------|---------|
|
|
157
|
+
| `twf check <file...>` | Parse + resolve — run after every edit |
|
|
158
|
+
| `twf symbols <file...>` | List all workflow/activity signatures |
|
|
159
|
+
| `twf symbols --json <file...>` | Machine-readable symbol output |
|
|
160
|
+
| `twf check --lenient <file...>` | Same checks; still prints every error but exits 0 instead of failing — for WIP iteration (it suppresses nothing) |
|
|
161
|
+
|
|
162
|
+
**Error format** (stderr): `<severity> [<kind>/<CODE>] at <file>:<line>:<col>: <message>` — e.g. `error [resolve/UNDEFINED_ACTIVITY] at order.twf:2:3: undefined activity: Foo`.
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## TWF Syntax
|
|
167
|
+
|
|
168
|
+
Full grammar: [`tools/spec/sections/`](../../../tools/spec/sections/) (or run `twf spec` for the concatenated view; `twf spec --list` for slugs). Quick reference: [`notation-reference.md`](./reference/notation-reference.md). Examples: [`notation-examples.md`](./reference/notation-examples.md). Common errors: [`common-errors.md`](./reference/common-errors.md).
|
|
169
|
+
|
|
170
|
+
All `.twf` must pass `twf check` before presenting to user. Activity bodies are free-form pseudocode — detail level depends on how obvious the behavior is (see [notation-examples.md](./reference/notation-examples.md#activity-body-detail)).
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Completion
|
|
175
|
+
|
|
176
|
+
The design is ready to present when both gates pass.
|
|
177
|
+
|
|
178
|
+
**Grammar / structure gate** (does it parse, resolve, and deploy?):
|
|
179
|
+
|
|
180
|
+
1. `twf check` passes with no errors
|
|
181
|
+
2. `twf symbols` lists all expected workflows and activities
|
|
182
|
+
3. Worker/namespace topology validates (when present)
|
|
183
|
+
|
|
184
|
+
**Design-quality gate** (is it a good Temporal design?) — these are *not* checked by any tool:
|
|
185
|
+
|
|
186
|
+
4. All I/O, time, and randomness live in activities (determinism)
|
|
187
|
+
5. Activities are idempotent, with the strategy stated per side-effecting activity
|
|
188
|
+
6. Failure modes have recovery strategies
|
|
189
|
+
7. The [Design Review](#design-review) rubric passes (call-site integrity, reachability, anti-pattern re-check)
|
|
190
|
+
|
|
191
|
+
The design is **not** ready on a clean `twf check` alone — gates 4-7 are where Temporal design quality actually lives. For the full checklist: [design-checklist.md](./reference/design-checklist.md). For complex control flow, parallel execution, or signal/timer races, suggest the TWF visualizer extension. Present a summary alongside the `.twf` file: key workflows, activity purposes, and notable design decisions.
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Handoff
|
|
196
|
+
|
|
197
|
+
The deliverable is the `.twf` file. **Produce/review `.twf`; `temporal-architect` routes implementation** — do not select authoring skills or orchestrate subagents from here. Alongside the `.twf`, note what `temporal-architect` and the authors need: target SDK/language, external system assumptions, and design decisions not captured in the notation.
|
|
198
|
+
|
|
199
|
+
This skill may run **in the main agent** (collaborative, interactive design — the common case, since `.twf` is the elevated surface the user designs *from*) or as a reviewer subagent dispatched by `temporal-architect`. `temporal-architect` decides which; either way, the output is the same `.twf` plus its handoff notes.
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Reference Index
|
|
204
|
+
|
|
205
|
+
Read only what the current design requires.
|
|
206
|
+
|
|
207
|
+
| Topic | When to Consult | File |
|
|
208
|
+
|-------|-----------------|------|
|
|
209
|
+
| Determinism & Idempotency | Replay safety and retry resilience review | [core-principles.md](./reference/core-principles.md) |
|
|
210
|
+
| Workflow Boundaries | Activity vs child workflow decision | [workflow-boundaries.md](./reference/workflow-boundaries.md) |
|
|
211
|
+
| Signal vs Update | Choosing between signal and update for external input | [signals-queries-updates.md](./topics/signals-queries-updates.md) |
|
|
212
|
+
| Notation Examples | Control flow, handlers, timers, nexus in TWF | [notation-examples.md](./reference/notation-examples.md) |
|
|
213
|
+
| Notation Reference | All TWF syntax constructs | [notation-reference.md](./reference/notation-reference.md) |
|
|
214
|
+
| `.twf` Conventions | File placement + comment conventions (impl-link, cross-domain stub) | [twf-conventions.md](./reference/twf-conventions.md) |
|
|
215
|
+
| Design Checklist | Final verification before presenting | [design-checklist.md](./reference/design-checklist.md) |
|
|
216
|
+
| Anti-Patterns | Common Temporal design mistakes | [anti-patterns.md](./reference/anti-patterns.md) |
|
|
217
|
+
| Reverse Engineering | Recovering `.twf` from existing code | [reverse-engineering.md](./reference/reverse-engineering.md) |
|
|
218
|
+
| Common Errors | Troubleshooting `twf check` parser/resolver errors | [common-errors.md](./reference/common-errors.md) |
|
|
219
|
+
| Primitives Reference | Temporal primitive lookup | [primitives-reference.md](./reference/primitives-reference.md) |
|
|
220
|
+
| Project Discovery Subagent | Scanning an existing repo on a bounded slice | [project-discovery-subagent.md](./reference/project-discovery-subagent.md) |
|
|
221
|
+
| Workers & Task Queues | Worker grouping, task queue routing, deployment | [task-queues.md](./topics/task-queues.md) |
|
|
222
|
+
| Namespaces | Deciding namespace count / boundaries | [namespaces.md](./reference/namespaces.md) |
|
|
223
|
+
| Nexus | Cross-namespace communication | [nexus.md](./topics/nexus.md) |
|
|
224
|
+
Topic deep-dives are in `reference/` and `topics/` — consult as needed during design.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# TWF Language Reference
|
|
2
|
+
|
|
3
|
+
The canonical grammar specification lives in [`tools/spec/sections/`](../../../../tools/spec/sections/) — one markdown file per topic, named `NN-slug.md`. The full concatenation is also available via `twf spec`; individual sections via `twf spec <slug>`.
|
|
4
|
+
|
|
5
|
+
Always consult the canonical spec for syntax questions. This redirect exists so that skill-internal links resolve.
|