@gate-forge/pack-task 0.7.0 → 0.8.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/README.md +80 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,6 +2,86 @@
|
|
|
2
2
|
|
|
3
3
|
Background-task discovery pack: a pure-TypeScript GPP/3 in-process detector that finds background-task signatures in `.ts`/`.js`/`.mjs` source — no Python subprocess, no execution, no external deps — plus an audit-trail entity-adapter schema and an example server that proves the five obligation contracts the pack claims.
|
|
4
4
|
|
|
5
|
+
## Engine-level proof: the queue observer
|
|
6
|
+
|
|
7
|
+
A background job's attempts, terminal state and idempotency live in the
|
|
8
|
+
QUEUE, so the engine reads the queue itself. A test's own "the job
|
|
9
|
+
succeeded" is never proof — exactly like a test's own HTTP status. A
|
|
10
|
+
repository opts in with an engine-owned `queueObserver` block in
|
|
11
|
+
`.gateforge.yml`:
|
|
12
|
+
|
|
13
|
+
```yaml
|
|
14
|
+
queueObserver:
|
|
15
|
+
kind: bullmq # or a module path whose default export is a factory
|
|
16
|
+
connection:
|
|
17
|
+
urlEnv: GATEFORGE_QUEUE_REDIS_URL # host/port form: {host, port}
|
|
18
|
+
queues:
|
|
19
|
+
- name: mailer # the queue the engine reads
|
|
20
|
+
taskResourceId: task.email.send
|
|
21
|
+
pollIntervalMs: 100 # transition-sampling interval (default 200)
|
|
22
|
+
terminalTimeoutMs: 30000 # bound on waiting for the delivery to settle
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
- The block lives in `.gateforge.yml`, so it is inside the trusted policy
|
|
26
|
+
digest: a candidate cannot point the engine at a queue it controls.
|
|
27
|
+
- Connection material never carries a secret inline — the URL form names
|
|
28
|
+
an environment variable the WITNESS process resolves privately; the
|
|
29
|
+
value is never sealed into a record, a report or argv.
|
|
30
|
+
- `kind: bullmq` reads the queue with the project's own `bullmq` and
|
|
31
|
+
`ioredis` (optional peers of `@gate-forge/witness`: install them next
|
|
32
|
+
to the app, `npm install --save-dev bullmq ioredis`). A project that
|
|
33
|
+
declares no BullMQ observer never installs or loads them; one that
|
|
34
|
+
declares it without them fails closed with that install command.
|
|
35
|
+
- WITHOUT the block the `task` namespace is **unavailable** (every
|
|
36
|
+
`task:*` contract fails closed, cause `VERIFIER_UNSUPPORTED`) and every
|
|
37
|
+
`engine-task` case blocks with a naming diagnostic. `gateforge init`
|
|
38
|
+
therefore recommends this pack's cases only when the block is
|
|
39
|
+
configured.
|
|
40
|
+
- `test-gates` hands the declaration to the witness it spawns
|
|
41
|
+
(`GATEFORGE_QUEUE_OBSERVER` + `GATEFORGE_QUEUE_OBSERVER_CONFIG`); a
|
|
42
|
+
repository without the block passes nothing and its spawn environment
|
|
43
|
+
is byte-identical.
|
|
44
|
+
|
|
45
|
+
### What a `deliver` case does
|
|
46
|
+
|
|
47
|
+
The engine produces the delivery, not the suite: it stamps the delivery
|
|
48
|
+
identity, the idempotency key and the attempt bound (taken from the
|
|
49
|
+
case's own `attempts` rule, so the policy declares the retry bound
|
|
50
|
+
exactly once), then polls the queue until every produced job settles and
|
|
51
|
+
seals what it read. `count` deliveries of one case share ONE idempotency
|
|
52
|
+
key — that is what makes a duplicate-key case a duplicate — while each
|
|
53
|
+
delivery gets its own identity.
|
|
54
|
+
|
|
55
|
+
### What an `attempts` rule settles
|
|
56
|
+
|
|
57
|
+
| Field | Meaning |
|
|
58
|
+
| --- | --- |
|
|
59
|
+
| `resourceId` | the task resource the case delivers to (must match the action) |
|
|
60
|
+
| `count` | the declared attempt bound: no job may exceed it, and the queue's own declared bound may not exceed it |
|
|
61
|
+
| `terminal` | `succeeded` (every job `completed`), `failed` (every job `failed`), `rejected` (every job failed on its FIRST attempt) |
|
|
62
|
+
| `minAttempts` (optional) | every job used at least this many attempts — "retries up to N" cannot be satisfied by a queue that never retried |
|
|
63
|
+
| `recoveredFromStall` (optional) | the engine's own timeline must show a lost-worker reclaim: the same job handed out again with UNCHANGED attempts and no failure reason (an error retry raises both) — and the delivery still settles |
|
|
64
|
+
|
|
65
|
+
A delivery case that declares no `attempts` rule settles nothing and is
|
|
66
|
+
blocked (`BEHAVIOR_BINDING_MISMATCH`), and a case that carries HTTP
|
|
67
|
+
attempts or a browser observation is rejected outright: those prove a
|
|
68
|
+
transport claim, not a background job.
|
|
69
|
+
|
|
70
|
+
### Proving it
|
|
71
|
+
|
|
72
|
+
`packages/cli/test/task-queue-behavior-e2e.test.ts` runs the real CLI,
|
|
73
|
+
the real witness and a REAL BullMQ application (`example/task-bullmq/`:
|
|
74
|
+
a queue plus worker processes, one of which is genuinely lost mid-job)
|
|
75
|
+
against a disposable Redis. Each contract ships a fail variant the engine
|
|
76
|
+
must block. The suite SKIPS unless `GATEFORGE_TEST_REDIS_URL` names a
|
|
77
|
+
live Redis — the engine's queue reader needs a real queue, and a fake one
|
|
78
|
+
would be a mock as proof:
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
docker run -d --rm --name gateforge-queue-redis -p 127.0.0.1:6379 redis:7-alpine
|
|
82
|
+
GATEFORGE_TEST_REDIS_URL=redis://127.0.0.1:6379 npm test -- task-queue-behavior-e2e
|
|
83
|
+
```
|
|
84
|
+
|
|
5
85
|
## How discovery works
|
|
6
86
|
|
|
7
87
|
The detector scans `.ts`/`.tsx`/`.js`/`.mjs` files with regex-based AST-light patterns (matching `pack-auth`'s strategy). It recognizes the task constructs below and reports its verdict through the discovery outcome's typed blocking vocabulary — the pack emits no resources and no classification signals of its own:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gate-forge/pack-task",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Background-task discovery pack: TS-only AST-light detector (GPP/3) for BullMQ / Bee-Queue / custom queues / message handlers / recurring jobs / @Task @Queue decorators, idempotency + retry-policy + terminal-on + observability contracts, audit-run entity-adapter schema.",
|
|
6
6
|
"type": "module",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"test": "vitest run"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@gate-forge/core": "^0.
|
|
30
|
-
"@gate-forge/plugin-protocol": "^0.
|
|
29
|
+
"@gate-forge/core": "^0.8.0",
|
|
30
|
+
"@gate-forge/plugin-protocol": "^0.8.0"
|
|
31
31
|
},
|
|
32
32
|
"publishConfig": {
|
|
33
33
|
"access": "public"
|