@uchibeke/gallivant 0.0.0-stage → 0.2.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/CONTRIBUTING.md +26 -0
- package/LICENSE +204 -0
- package/README.md +201 -2
- package/SECURITY.md +19 -0
- package/bin/gallivant.mjs +257 -0
- package/bin/package-plugin.mjs +16 -0
- package/bin/release-live.mjs +29 -0
- package/bin/release-package.mjs +23 -0
- package/bin/session-runtime.mjs +13 -0
- package/bin/task-delivery-state.mjs +12 -0
- package/docs/README.md +70 -0
- package/docs/agent-setup.md +214 -0
- package/docs/app.md +111 -0
- package/docs/architecture.md +265 -0
- package/docs/chains.md +102 -0
- package/docs/codex-cloud.md +284 -0
- package/docs/commands.md +620 -0
- package/docs/config.md +430 -0
- package/docs/execution.md +796 -0
- package/docs/guardrails.md +311 -0
- package/docs/install.md +338 -0
- package/docs/launch.md +42 -0
- package/docs/learning.md +369 -0
- package/docs/network-recovery.md +101 -0
- package/docs/openai-agents.md +457 -0
- package/docs/prd.md +246 -0
- package/docs/preparation.md +110 -0
- package/docs/release-qualification.md +196 -0
- package/docs/releasing.md +140 -0
- package/docs/runtime-environment.md +113 -0
- package/docs/task-delivery.md +476 -0
- package/docs/tasks.md +739 -0
- package/lib/aport.mjs +95 -0
- package/lib/attribution.mjs +95 -0
- package/lib/block.mjs +89 -0
- package/lib/capabilities.mjs +3 -0
- package/lib/chains.mjs +222 -0
- package/lib/codex_cloud.mjs +160 -0
- package/lib/codex_cloud_config.mjs +20 -0
- package/lib/codex_cloud_input.mjs +49 -0
- package/lib/codex_cloud_result.mjs +74 -0
- package/lib/commands/doctor.mjs +457 -0
- package/lib/commands/init.mjs +34 -0
- package/lib/commands/learn.mjs +54 -0
- package/lib/commands/new.mjs +47 -0
- package/lib/commands/ready.mjs +45 -0
- package/lib/commands/register.mjs +195 -0
- package/lib/commands/resume.mjs +224 -0
- package/lib/commands/serve.mjs +349 -0
- package/lib/commands/start.mjs +247 -0
- package/lib/commands/start_services.mjs +22 -0
- package/lib/commands/status.mjs +150 -0
- package/lib/commands/task.mjs +73 -0
- package/lib/commands/up.mjs +228 -0
- package/lib/commands/why.mjs +143 -0
- package/lib/config.mjs +461 -0
- package/lib/context.mjs +100 -0
- package/lib/control.mjs +202 -0
- package/lib/control_contract.mjs +16 -0
- package/lib/coordinator.mjs +19 -0
- package/lib/credential.mjs +161 -0
- package/lib/daemon.mjs +156 -0
- package/lib/deliverable.mjs +357 -0
- package/lib/events.mjs +261 -0
- package/lib/executable.mjs +31 -0
- package/lib/execution.mjs +631 -0
- package/lib/execution_contract.mjs +15 -0
- package/lib/execution_input.mjs +4 -0
- package/lib/execution_io.mjs +94 -0
- package/lib/execution_journal.mjs +69 -0
- package/lib/execution_preparation.mjs +29 -0
- package/lib/execution_result.mjs +266 -0
- package/lib/fs.mjs +133 -0
- package/lib/gh.mjs +289 -0
- package/lib/git.mjs +434 -0
- package/lib/harness.mjs +521 -0
- package/lib/harness_log.mjs +432 -0
- package/lib/hash.mjs +16 -0
- package/lib/identity.mjs +98 -0
- package/lib/learning.mjs +654 -0
- package/lib/learning_contract.mjs +2 -0
- package/lib/learning_data.mjs +135 -0
- package/lib/learning_input.mjs +111 -0
- package/lib/learning_qualification.mjs +67 -0
- package/lib/learning_signer.mjs +151 -0
- package/lib/learning_store.mjs +88 -0
- package/lib/log.mjs +53 -0
- package/lib/network_diagnostics.mjs +64 -0
- package/lib/network_recovery.mjs +42 -0
- package/lib/notify.mjs +58 -0
- package/lib/openai_agents.mjs +373 -0
- package/lib/openai_agents_config.mjs +14 -0
- package/lib/openai_agents_http.mjs +87 -0
- package/lib/openai_agents_input.mjs +15 -0
- package/lib/openai_agents_sources.mjs +112 -0
- package/lib/owner_delivery.mjs +443 -0
- package/lib/plugin_package.mjs +340 -0
- package/lib/prd.mjs +635 -0
- package/lib/preparation_agents.mjs +33 -0
- package/lib/preparation_codex.mjs +212 -0
- package/lib/probe.mjs +126 -0
- package/lib/prompt.mjs +238 -0
- package/lib/provider_health.mjs +55 -0
- package/lib/public-format.mjs +31 -0
- package/lib/public_output.mjs +49 -0
- package/lib/release_package.mjs +154 -0
- package/lib/repository_files.mjs +86 -0
- package/lib/run.mjs +385 -0
- package/lib/run_log.mjs +94 -0
- package/lib/runtime-environment.mjs +87 -0
- package/lib/runtime_dependencies.mjs +15 -0
- package/lib/runtime_node.mjs +107 -0
- package/lib/runtime_state.mjs +174 -0
- package/lib/sources/index.mjs +27 -0
- package/lib/sources/prd.mjs +50 -0
- package/lib/start_contract.mjs +37 -0
- package/lib/state.mjs +246 -0
- package/lib/task_allowance.mjs +31 -0
- package/lib/task_completion.mjs +61 -0
- package/lib/task_contract.mjs +450 -0
- package/lib/task_delivery.mjs +219 -0
- package/lib/task_delivery_cancel.mjs +34 -0
- package/lib/task_delivery_contract.mjs +61 -0
- package/lib/task_delivery_mcp.mjs +40 -0
- package/lib/task_delivery_store.mjs +43 -0
- package/lib/task_delivery_view.mjs +88 -0
- package/lib/task_environment.mjs +281 -0
- package/lib/task_prepare.mjs +224 -0
- package/lib/task_store.mjs +38 -0
- package/lib/tasks.mjs +513 -0
- package/lib/tick.mjs +1635 -0
- package/lib/time.mjs +36 -0
- package/lib/tracker/assets.mjs +43 -0
- package/lib/tracker/pages.mjs +320 -0
- package/lib/tracker/runs.mjs +102 -0
- package/lib/tracker/stream.mjs +74 -0
- package/lib/tracker_process.mjs +107 -0
- package/lib/verification_sandbox.mjs +181 -0
- package/node_modules/smol-toml/LICENSE +24 -0
- package/node_modules/smol-toml/README.md +605 -0
- package/node_modules/smol-toml/dist/date.d.ts +41 -0
- package/node_modules/smol-toml/dist/date.js +156 -0
- package/node_modules/smol-toml/dist/error.d.ts +37 -0
- package/node_modules/smol-toml/dist/error.js +67 -0
- package/node_modules/smol-toml/dist/extract.js +289 -0
- package/node_modules/smol-toml/dist/index.cjs +770 -0
- package/node_modules/smol-toml/dist/index.d.ts +44 -0
- package/node_modules/smol-toml/dist/index.js +34 -0
- package/node_modules/smol-toml/dist/parse.d.ts +73 -0
- package/node_modules/smol-toml/dist/parse.js +164 -0
- package/node_modules/smol-toml/dist/primitive.js +151 -0
- package/node_modules/smol-toml/dist/stringify.d.ts +32 -0
- package/node_modules/smol-toml/dist/stringify.js +219 -0
- package/node_modules/smol-toml/dist/struct.js +156 -0
- package/node_modules/smol-toml/dist/util.d.ts +43 -0
- package/node_modules/smol-toml/dist/util.js +57 -0
- package/node_modules/smol-toml/package.json +68 -0
- package/npm-shrinkwrap.json +1823 -0
- package/package.json +105 -4
- package/templates/claude-settings.json +18 -0
- package/templates/passport.gallivant.json +83 -0
- package/templates/plugin/bundled-runtime.json +26 -0
- package/templates/plugin/schemas/mcp.schema.json +120 -0
- package/templates/plugin/schemas/plugin.schema.json +65 -0
- package/templates/plugin/task-delivery.SKILL.md +60 -0
- package/templates/prd.md +32 -0
- package/templates/tracker/tracker.css +301 -0
- package/templates/tracker/tracker.js +721 -0
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
# Embed task delivery in another application
|
|
2
|
+
|
|
3
|
+
The package exposes Gallivant's task/readiness/review decisions and provider
|
|
4
|
+
transports to a trusted host through a scoped operation API or MCP. The host
|
|
5
|
+
supplies authentication and authorization, tenant/region routing, repository
|
|
6
|
+
authority, HTTP transport, durable storage, scheduling and any web/plugin UI.
|
|
7
|
+
Installing the package does not deploy a service or configure those boundaries.
|
|
8
|
+
|
|
9
|
+
**APort is the reference integration**, not a required host for these exports.
|
|
10
|
+
The examples below use its injected adapters and deployment names; another host
|
|
11
|
+
must enforce the same authorization, ownership, persistence and recovery
|
|
12
|
+
contracts. In the APort integration, APort owns publication and the host
|
|
13
|
+
responsibilities above. Its existing
|
|
14
|
+
`aporthq/agent-passport/aport-task-delivery-mcp` job produced merged
|
|
15
|
+
[PR #414](https://github.com/aporthq/agent-passport/pull/414); reuse that integration.
|
|
16
|
+
The M5/M6 notes below preserve that integration's milestone evidence and gates;
|
|
17
|
+
they do not certify another host or supply a public UI, database or competing
|
|
18
|
+
runner.
|
|
19
|
+
|
|
20
|
+
## Installed exports
|
|
21
|
+
|
|
22
|
+
Core `0.2.0`, task schema `1`, execution schema `1`, operation schema `1`.
|
|
23
|
+
The candidate digest comes from the emitted `runtime.json`/`manifest.json`;
|
|
24
|
+
pin the artifact produced from the eventual human-merged commit, not this branch.
|
|
25
|
+
|
|
26
|
+
| Import | Public API |
|
|
27
|
+
| --- | --- |
|
|
28
|
+
| `@uchibeke/gallivant/tasks` | `createTaskService`, `TASK_VERSION`; same service used by CLI task commands |
|
|
29
|
+
| `@uchibeke/gallivant/capabilities` | `executionCapabilities`, `capabilitiesFor`, setup/runtime requirements |
|
|
30
|
+
| `@uchibeke/gallivant/task-delivery` | `createTaskDelivery` scoped operation dispatcher |
|
|
31
|
+
| `@uchibeke/gallivant/task-delivery/contracts` | `TASK_OPERATIONS`, versions, compatibility handshake, UI resource configuration |
|
|
32
|
+
| `@uchibeke/gallivant/task-delivery/views` | `taskView`, `modelSummary`; saved observations only |
|
|
33
|
+
| `@uchibeke/gallivant/task-delivery/store` | `createDeliveryStore`, `scopeKey`; single-host durable receipt adapter |
|
|
34
|
+
| `@uchibeke/gallivant/task-delivery/mcp` | `registerTaskDelivery`; lazy optional MCP SDK peer `1.32.1` |
|
|
35
|
+
| `@uchibeke/gallivant/execution` | Existing `makeExecution`, cached inspect and coordinator reconciliation |
|
|
36
|
+
| `@uchibeke/gallivant/providers/openai-agents` | Existing managed session transport and setup checks |
|
|
37
|
+
| `@uchibeke/gallivant/providers/codex-cloud` | Existing native CLI transport and setup checks |
|
|
38
|
+
| `@uchibeke/gallivant/runtime/coordinator` | `createCoordinator` fenced bounded wake envelope |
|
|
39
|
+
| `@uchibeke/gallivant/runtime/node` | `createNodeOwnerStore`, `createNodeCoordinator`, requirements |
|
|
40
|
+
| `@uchibeke/gallivant/runtime/state` | Check, migrate, private backup and fresh-namespace rollback |
|
|
41
|
+
| `@uchibeke/gallivant/runtime/node/dependencies` | State/config/log/identity constructors, canonical tick/readiness/controls, bounded log reader and atomic storage helpers for injected Node adapters |
|
|
42
|
+
| `@uchibeke/gallivant/plugin-package` | Single reproducible package builder and public metadata validator |
|
|
43
|
+
|
|
44
|
+
Imports read no operator configuration, invoke no provider and start no daemon.
|
|
45
|
+
Existing `./lib/*` compatibility imports remain; consumers use the named exports.
|
|
46
|
+
No new CLI daemon is required. Existing registry/run/source files, tracker routes,
|
|
47
|
+
Command Center SSE/history, statuses and controls retain their version-1 shapes.
|
|
48
|
+
|
|
49
|
+
## Scoped operation adapter
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
import { createTaskDelivery } from '@uchibeke/gallivant/task-delivery';
|
|
53
|
+
import { createDeliveryStore } from '@uchibeke/gallivant/task-delivery/store';
|
|
54
|
+
const delivery = createTaskDelivery({
|
|
55
|
+
manifest: emittedRuntimeManifest, // load this installed artifact's runtime.json
|
|
56
|
+
authorize: aportAuthorize, // validate OAuth/audience/region/repository on EVERY call
|
|
57
|
+
contextFor: aportScopedNodeContext,
|
|
58
|
+
store: createDeliveryStore('/durable/preview/delivery'),
|
|
59
|
+
schedule: aportEnqueueWake,
|
|
60
|
+
secretsFor: aportPrivateRedactionValues,
|
|
61
|
+
});
|
|
62
|
+
const task = await delivery.dispatch('prepare', {
|
|
63
|
+
repositoryId: 'widget', harness: 'openai-agents',
|
|
64
|
+
text: 'Describe the requested implementation and its constraints.',
|
|
65
|
+
completion: { target: 'delivery_ready' }, // optional; default shown
|
|
66
|
+
allowance: { budgetUsd: 1, runtimeMs: 60000 },
|
|
67
|
+
operationId: 'request-1', expectedRevision: 0,
|
|
68
|
+
}, authenticatedIdentity);
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`authorize` must return validated `tenant`, `account`, `environment`, `region`,
|
|
72
|
+
`scopes` (`task-delivery:read` or `task-delivery:write`) and authorized repository
|
|
73
|
+
IDs. Identity comes from APort's authenticated request context, never tool input.
|
|
74
|
+
`contextFor(scope, repositoryId)` supplies `{ctx, repository:{dir,repo,context}}`.
|
|
75
|
+
Each context and durable home must be isolated by all four scope dimensions;
|
|
76
|
+
credential/GitHub/provider resolution must enforce the same scope. Selected
|
|
77
|
+
context IDs map to trusted repository paths. No paths, endpoints or credentials
|
|
78
|
+
are accepted by the public schemas. Do not supply `taskOptions` in production;
|
|
79
|
+
that dependency injection seam is used by deterministic consumer fixtures.
|
|
80
|
+
|
|
81
|
+
The durable receipt store interface is `read(scope)` and
|
|
82
|
+
`transaction(scope, async (data, save) => result)`; `save` must commit before it
|
|
83
|
+
resolves. It serializes the scope for the entire mutation and retains task
|
|
84
|
+
ownership, exact request fingerprints, intent, acknowledgement and pending wake.
|
|
85
|
+
This release's filesystem adapter supports one host on a durable volume. APort
|
|
86
|
+
can supply another adapter only with equivalent tested transaction/ownership
|
|
87
|
+
semantics. Shared physical storage alone grants no authority.
|
|
88
|
+
Delivery mutations also claim the scoped home's daemon ownership lock before
|
|
89
|
+
saving intent and hold it through task effects, receipt acknowledgement and wake
|
|
90
|
+
scheduling. Backup, migration and coordinator wakes therefore refuse concurrent
|
|
91
|
+
ownership; retry the same operation ID after the owner releases. The scheduler
|
|
92
|
+
must enqueue a future wake, never execute a coordinator inline. Read operations
|
|
93
|
+
do not acquire this owner or create provider pollers.
|
|
94
|
+
The dispatcher requires its own emitted `runtime.json` as `manifest`; it captures
|
|
95
|
+
that identity at construction and checks the exact installed version/digest under
|
|
96
|
+
ownership on every mutation, including receipt replays. Migrate each scoped home
|
|
97
|
+
before enabling requests. After migration to another artifact, retire old request
|
|
98
|
+
handlers; never substitute the namespace's new pin as an old handler's manifest.
|
|
99
|
+
Consumers upgrading from the earlier dispatcher signature must add this manifest
|
|
100
|
+
and initialize the scoped pin. Reads do not validate or replace that pin.
|
|
101
|
+
|
|
102
|
+
Capability responses expose `repositories[].completion` with `defaultTarget` and
|
|
103
|
+
supported `targets`. The shared prepare schema accepts only
|
|
104
|
+
`completion: { target: 'delivery_ready' | 'integrated' }`; the selected policy is
|
|
105
|
+
persisted through intake and implementation ownership. Task, list, model and
|
|
106
|
+
evidence projections expose `completion` from saved coordinator observations.
|
|
107
|
+
For `delivery_ready`, a qualified saved handoff stops automatic observation and
|
|
108
|
+
fixes. Explicit queued controls reopen the normal workflow. `integrated` and
|
|
109
|
+
legacy runs retain monitoring. Host schedulers use the exported
|
|
110
|
+
`coordinatorEntryActive` predicate instead of treating every `ready-for-human`
|
|
111
|
+
entry as active; the predicate requires matching repository, PR, base, head and
|
|
112
|
+
gate proof. Read `completion.monitoring` for the saved view's monitoring status.
|
|
113
|
+
Use `completion.status`, not a provider success or a terminal PR state, to report
|
|
114
|
+
fulfillment. `awaiting_integration` means the qualified PR is still being watched;
|
|
115
|
+
`blocked` or `unverified` requires attention. Both targets use the GitHub PR
|
|
116
|
+
observation adapter today. The milestone names are portable, but no additional
|
|
117
|
+
artifact, deployment or non-GitHub adapter is advertised. See [task milestones](tasks.md#choose-the-delivery-milestone)
|
|
118
|
+
for evidence, cancellation and legacy behavior. The policy never grants merge
|
|
119
|
+
permission or changes the allowance.
|
|
120
|
+
|
|
121
|
+
New natural-language publication clauses use the core's versioned exact-source
|
|
122
|
+
ownership contract. `completion.obligations` exposes their pending/fulfilled state
|
|
123
|
+
and matching coordinator evidence. `TASK_DELIVERY_SCOPE` is a before-effects
|
|
124
|
+
clarification refusal, durably acknowledged on the exact operation identity; it
|
|
125
|
+
must not be retried with changed text under that same identity. Ask the owner to
|
|
126
|
+
clarify the complete request and then use a new preparation identity. See
|
|
127
|
+
[natural-language ownership](tasks.md) for supported syntax and limitations.
|
|
128
|
+
|
|
129
|
+
Literal examples must have matching quote/backtick delimiters in new requests and
|
|
130
|
+
answers. Saved ownership contracts keep their approved spans and historical
|
|
131
|
+
unclosed-literal handling. Malformed mixed backtick runs that previously exposed a
|
|
132
|
+
publication clause can fail validation under the corrected scanner; their records
|
|
133
|
+
are not rewritten. The owner must clarify a new request rather than automatically
|
|
134
|
+
continuing publication from that malformed contract. PR-modified UI/document objects, database transactions, data
|
|
135
|
+
structure operations and product-user consent are implementation requirements;
|
|
136
|
+
unqualified Git directions, owner approval and publication conditions remain
|
|
137
|
+
workflow controls. Only those concrete technical objects are excluded: unrelated
|
|
138
|
+
or coordinated restrictions remain visible. Statement separators end independent
|
|
139
|
+
constraints, while an unfinished colon prefix keeps its scope across blank lines.
|
|
140
|
+
This is a bounded grammar, not a general natural-language authorization model.
|
|
141
|
+
|
|
142
|
+
All mutations require operationId and expectedRevision; prepare uses revision 0.
|
|
143
|
+
Preparation does not authorize implementation. Start requires `run:true` and the
|
|
144
|
+
current exact readiness decision. Answers bind saved question IDs. Stable keys
|
|
145
|
+
replay saved results; changed payloads conflict. Lost execution acknowledgement
|
|
146
|
+
retains the existing dispatch intent and cannot automatically submit twice.
|
|
147
|
+
Controls call the same queue as CLI/tracker and carry stable request identity.
|
|
148
|
+
The scheduler may retry a pending wake without repeating inference.
|
|
149
|
+
Scoped allowance is pinned into implementation metadata after subtracting
|
|
150
|
+
preparation charges/reservations and elapsed time. Later runs use the saved cap,
|
|
151
|
+
subtract known local charges and completed runtime, and retain the remote
|
|
152
|
+
execution ledger's aggregate reservations. Unknown local cost or duration refuses
|
|
153
|
+
further dispatch. Providers without billing hard caps remain explicitly described
|
|
154
|
+
as such; an authorization limit is not a promise about their billing controls.
|
|
155
|
+
|
|
156
|
+
Tools are generated from `TASK_OPERATIONS`: capabilities, prepare, answer,
|
|
157
|
+
resume, validate, start, list, inspect, evidence, logs and control. MCP SDK
|
|
158
|
+
registration prefixes each name with `task_`; there is one schema/annotation
|
|
159
|
+
mapping. Preparation, readiness, start and controls are writes with external
|
|
160
|
+
effects. Reads inspect saved state and create no provider poller. MCP registration
|
|
161
|
+
expects APort's per-request `identityFor` and authorized built `readResource`.
|
|
162
|
+
Capabilities return at most 100 authorized repositories, sorted by opaque ID,
|
|
163
|
+
with `truncated` and `nextCursor`. Pass `nextCursor` as `cursor` to continue;
|
|
164
|
+
a null cursor ends the traversal. Every page reauthorizes the account. Repository
|
|
165
|
+
IDs and provider availability, preparation, setup, cost and control fields appear in both
|
|
166
|
+
MCP model content and UI metadata, so a client can construct `prepare` directly.
|
|
167
|
+
The optional cursor extends operation schema version 1 without changing existing
|
|
168
|
+
empty-input calls. Restart discovery to include newly granted IDs before a cursor.
|
|
169
|
+
|
|
170
|
+
APort owns transport-level OAuth discovery/challenges, origin/audience validation,
|
|
171
|
+
credential rotation, request limits, quota, retention and production authorization.
|
|
172
|
+
|
|
173
|
+
Full UI views include questions, brief, harness/cost/setup, allowance, progress,
|
|
174
|
+
bounded logs, artifact IDs/hashes, source snapshots, PR URLs and supported controls.
|
|
175
|
+
They remove configured private path prefixes and redact resolved secrets;
|
|
176
|
+
repository-relative artifact paths remain available in authorized UI views.
|
|
177
|
+
Model output includes bounded capability discovery, task/revision/status,
|
|
178
|
+
repository/harness identity, completion, question IDs and text, supported controls,
|
|
179
|
+
blocked-task recovery guidance and the PR link. List pages include question counts;
|
|
180
|
+
inspect and mutation responses include the questions. Raw logs and brief bytes
|
|
181
|
+
stay in UI metadata. Artifact download authorization/storage remains APort's
|
|
182
|
+
job; the public dispatcher exposes stable manifests, not arbitrary file retrieval.
|
|
183
|
+
|
|
184
|
+
`uiResourceConfiguration` accepts the single registered `ui://` URI, dedicated
|
|
185
|
+
HTTPS origin and exact CSP connect/resource origins. Global sidebar and thread
|
|
186
|
+
panel entrypoints share it. HTML is supplied from the built APort UI (2,000,000 bytes
|
|
187
|
+
maximum, shared by the package builder and runtime reader), served as
|
|
188
|
+
`text/html;profile=mcp-app`. Fixture HTML proves resource
|
|
189
|
+
wiring only. No final UI or host availability is claimed here.
|
|
190
|
+
|
|
191
|
+
## Runtime and existing Pages deployment
|
|
192
|
+
|
|
193
|
+
Node 22 is the supported workflow runtime. Inject `ctx.state`, `gh`, `git`,
|
|
194
|
+
`credential`, `identity`, `notify`, `executionFor`, source/brief storage and clock
|
|
195
|
+
using the predecessor context contracts. The runtime calls `makeTick` for all
|
|
196
|
+
review decisions. Durable home stores registry, tasks, briefs, provider intent,
|
|
197
|
+
events and artifacts; neither container disk nor Pages temporary files suffice.
|
|
198
|
+
Bounded entry/chain batches run on each externally scheduled wake. Active chains
|
|
199
|
+
rotate by a persisted name cursor; done, cancelled and stopped history consumes
|
|
200
|
+
no batch slots. Completion or cancellation cannot shift the remaining window.
|
|
201
|
+
`maxChains: 0` explicitly disables chain processing for that coordinator. Entry
|
|
202
|
+
and chain cursors commit only after a successful tick. The canonical tick's chain
|
|
203
|
+
poll deadline is persisted too: pending batches finish their sweep, then chain
|
|
204
|
+
reads wait for `poll_seconds` even across process restarts. Faster wakes continue
|
|
205
|
+
entry/provider reconciliation without advancing the chain cursor. The next wake
|
|
206
|
+
is scheduled before reconciliation, so a crash cannot lose recovery scheduling.
|
|
207
|
+
|
|
208
|
+
`createNodeOwnerStore({home,durable:true,replicas:1})` uses the existing daemon
|
|
209
|
+
exclusion plus persisted monotonic fence/instance. It cannot expire a live owner;
|
|
210
|
+
the stale-process check recovers after eviction. A UI or repeated callback never
|
|
211
|
+
creates a concurrent owner. Do not share this lock across hosts or advertise it as
|
|
212
|
+
a distributed lease. Injected distributed stores must atomically enforce fencing
|
|
213
|
+
at their write boundaries. The wrapper guards context effects and retains provider
|
|
214
|
+
dispatch ambiguity through the existing execution service.
|
|
215
|
+
|
|
216
|
+
Before wake-up, migrate/pin the exact runtime artifact. Supply the emitted
|
|
217
|
+
`runtime.json` to `createNodeCoordinator({ctx,store,schedule,manifest})`.
|
|
218
|
+
The coordinator refuses a different active-job digest. Compatible patches keep
|
|
219
|
+
task/provider/brief identities; drain jobs before staging a different artifact.
|
|
220
|
+
No running code is silently upgraded. The public API's pre-1.0 compatibility
|
|
221
|
+
window is `0.2.x`, with operation/task/execution wire schemas all `1`; other
|
|
222
|
+
versions need migration.
|
|
223
|
+
|
|
224
|
+
The portable contracts/views/wake envelope have no Node dependencies. The complete
|
|
225
|
+
task service and both transport implementations still require Node filesystem,
|
|
226
|
+
child processes, Git/gh and isolated verification. `npm test` bundles the portable
|
|
227
|
+
entries for browsers and checks their shared liveness predicates. The installed
|
|
228
|
+
artifact check (`test:plugin-package`) repeats those bundles and confirms the full
|
|
229
|
+
Node runtime rejects a browser target, separately from actual Node execution. This
|
|
230
|
+
is **not** a tested Workers-native workflow runtime or deployed Pages endpoint.
|
|
231
|
+
The smallest remedy: keep existing Pages OAuth/MCP/UI; connect its authenticated
|
|
232
|
+
runtime binding to one Node 22 coordinator with a durable volume and external
|
|
233
|
+
wake-ups. Evaluate an already supported Node runtime or Cloudflare Container in
|
|
234
|
+
the existing account before provisioning. No mandatory new Worker/VPS is proposed.
|
|
235
|
+
|
|
236
|
+
Cloud additionally needs the pinned Codex CLI and trusted operator sign-in. Its
|
|
237
|
+
predecessor currently blocks new dispatch until a documented environment-to-repo
|
|
238
|
+
check can be implemented/qualified. Preserve that block; native Cloud HTTP,
|
|
239
|
+
public credential delegation, cancellation and interrupt are not invented.
|
|
240
|
+
Agents API credentials, exact model/environment access and inference/compute
|
|
241
|
+
allowance must be supplied by the authorized account; no subscription entitlement
|
|
242
|
+
is inferred. Both transports remain exported and covered by installed fixtures.
|
|
243
|
+
|
|
244
|
+
The current registry declares bounded natural-language preparation for
|
|
245
|
+
`openai-agents`: `agents-text-only-v1`, authority `text-only`, environment `none`.
|
|
246
|
+
Its creation request disables tools and delegation; effective session and output
|
|
247
|
+
checks enforce that boundary. Claude and Codex have their own registered local
|
|
248
|
+
preparation boundaries. Codex Cloud, Gemini, OpenCode and Goose expose
|
|
249
|
+
`canPrepare:false` with a remedy; selecting them for preparation cannot silently
|
|
250
|
+
fall back to another provider or gain implementation authority.
|
|
251
|
+
|
|
252
|
+
Capability responses describe this implementation, not account entitlement or a
|
|
253
|
+
completed live workflow. Installed fixtures cover shared API/Cloud transport,
|
|
254
|
+
recovery and publication; preparation qualification and live account prerequisites
|
|
255
|
+
remain explicit in [preparation](preparation.md), [Agents setup](openai-agents.md)
|
|
256
|
+
and [Cloud availability](codex-cloud.md). The package can be integrated through
|
|
257
|
+
MCP or the scoped operation API, but is not itself a deployed multi-tenant service.
|
|
258
|
+
|
|
259
|
+
## Build, configure, upgrade and rollback
|
|
260
|
+
|
|
261
|
+
Build from the same tagged/merged source and explicit core version. Commit or
|
|
262
|
+
remove npm ignore/configuration controls before a public build, including ignored
|
|
263
|
+
controls or directories under the runtime payload. Internal builds record these
|
|
264
|
+
changes and remain development fixtures:
|
|
265
|
+
|
|
266
|
+
```sh
|
|
267
|
+
npm ci --ignore-scripts
|
|
268
|
+
node bin/package-plugin.mjs --config /private/aport-package.json --validate-public
|
|
269
|
+
npm run package:plugin -- --config /private/aport-package.json --out /private/candidate \
|
|
270
|
+
--core-version 0.2.0 --source-commit <40-character-merged-commit>
|
|
271
|
+
# For development only, add --internal; keep fixture:true in the config.
|
|
272
|
+
npm install --ignore-scripts --prefix /private/candidate-runtime /private/candidate/uchibeke-gallivant-0.2.0.tgz
|
|
273
|
+
node /private/candidate-runtime/node_modules/@uchibeke/gallivant/bin/task-delivery-state.mjs check \
|
|
274
|
+
--home /durable/preview --manifest /private/candidate/runtime.json
|
|
275
|
+
node /private/previous-runtime/node_modules/@uchibeke/gallivant/bin/task-delivery-state.mjs backup \
|
|
276
|
+
--home /durable/preview --manifest /private/previous/runtime.json --out /private/backup
|
|
277
|
+
node /private/candidate-runtime/node_modules/@uchibeke/gallivant/bin/task-delivery-state.mjs migrate \
|
|
278
|
+
--home /durable/preview --manifest /private/candidate/runtime.json
|
|
279
|
+
# Roll back package AND state into a fresh namespace, then switch the existing binding.
|
|
280
|
+
npm install --ignore-scripts --prefix /private/previous-runtime /private/previous/uchibeke-gallivant-0.2.0.tgz
|
|
281
|
+
node /private/previous-runtime/node_modules/@uchibeke/gallivant/bin/task-delivery-state.mjs rollback \
|
|
282
|
+
--backup /private/backup --out /durable/restored --manifest /private/previous/runtime.json
|
|
283
|
+
npm run test:plugin-package
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Replace the illustrative `/private/...` and `/durable/...` paths with private,
|
|
287
|
+
writable locations on your host. The upgrade example assumes the previous
|
|
288
|
+
package is installed under `/private/previous-runtime`; use that installed
|
|
289
|
+
artifact for backup. First-time setup has no previous namespace to back up.
|
|
290
|
+
Separate installation prefixes keep candidate and rollback versions out of the
|
|
291
|
+
source checkout and avoid depending on a global executable or shell `PATH`.
|
|
292
|
+
|
|
293
|
+
Stop new intake/wake-ups and the old coordinator before backup/migration. Active
|
|
294
|
+
jobs retain their runtime; incompatible changes fail with this remedy. Backups
|
|
295
|
+
are private, outside public packages, omit operator config/auth, and preserve
|
|
296
|
+
task/run/provider/source identities. Back up with the currently pinned, pre-upgrade
|
|
297
|
+
manifest; a candidate manifest cannot label an older namespace's backup. Restore
|
|
298
|
+
requires both the backup envelope and copied runtime pin to match the selected
|
|
299
|
+
artifact. Unpinned legacy state can be backed up with an explicit compatible
|
|
300
|
+
manifest and must be migrated before enabling its coordinator.
|
|
301
|
+
Verify store consistency before switching bindings. Keep old runtime artifacts
|
|
302
|
+
and credential bindings available for rollback; do not merge/upgrade live jobs.
|
|
303
|
+
|
|
304
|
+
A qualified `delivery_ready` handoff releases its runtime pin even while its
|
|
305
|
+
retained registry state is `ready-for-human`. Pending controls, live or uncollected
|
|
306
|
+
execution, unresolved intake/receipts and active chains still prevent migration.
|
|
307
|
+
Pending learning delivery audits also retain the pin and keep coordinator wake-ups
|
|
308
|
+
active. They retry separately after handoff without polling the settled provider,
|
|
309
|
+
reopening PR review or launching another agent turn; a successful audit drains
|
|
310
|
+
the saved outbox and releases that remaining work.
|
|
311
|
+
Legacy tasks, `integrated` tasks awaiting merge and unresolved `needs-human` work
|
|
312
|
+
retain their pins; the scheduling pause alone does not make a namespace idle.
|
|
313
|
+
|
|
314
|
+
Package config supplies publisher `APort`, exact endpoint, `resource` configuration,
|
|
315
|
+
owner-selected support email/product/support/privacy/terms/license URLs and explicit
|
|
316
|
+
asset paths (`assets.ui`, `assets.icon`, `assets.screenshots`). The emitted combined
|
|
317
|
+
skills/MCP ZIP has one HTTPS MCP server, Apache-2.0 license and explicit assets.
|
|
318
|
+
Runtime tarball, recipe, operation schemas and manifest record source commit,
|
|
319
|
+
core/contracts, dependency lock, payload/asset/schema hashes and artifact SHA-256.
|
|
320
|
+
The published runtime carries `npm-shrinkwrap.json`, so the installed builder
|
|
321
|
+
uses the same dependency lock as the source build.
|
|
322
|
+
No credential headers or unrelated tree files enter the plugin. Keep input config,
|
|
323
|
+
private backups, provider logs and reviewer credentials outside the output.
|
|
324
|
+
|
|
325
|
+
Public packaging also requires `oauth`, `review`, and `publication`. The OAuth
|
|
326
|
+
input deliberately matches APort's currently implemented registered public client:
|
|
327
|
+
`type: "oauth"`, `client: { mode: "provided", clientId: "<registered ID>",
|
|
328
|
+
tokenEndpointAuthMethod: "none" }`, and `baseScopes` copied from the public
|
|
329
|
+
authorization server's actual discovery/tool contract. APort's public scopes are
|
|
330
|
+
`tasks:read`, `tasks:write`, `tasks:check`, and `tasks:control`; they are distinct
|
|
331
|
+
from Gallivant's internal delivery scopes. The builder validates OAuth scope-token
|
|
332
|
+
syntax and preserves the deployment's supplied values without translating them.
|
|
333
|
+
Verify exact agreement with live discovery before connecting. Optional `authorizationUrl` and
|
|
334
|
+
`tokenUrl` override discovery. Register the exact redirect URI displayed by the
|
|
335
|
+
host's MCP management page in APort's `TASK_DELIVERY_CLIENTS`; do not assume the
|
|
336
|
+
GitHub login callback is the host callback. No client secret belongs in this
|
|
337
|
+
public PKCE configuration. DCR/CIMD and confidential clients are not implemented
|
|
338
|
+
by this APort deployment and are not accepted by its packager.
|
|
339
|
+
|
|
340
|
+
Optional `oauth.defaultScopes` uses the same token validation as `baseScopes`,
|
|
341
|
+
but permits an empty array. Per OpenAI's OAuth configuration reference, `[]`
|
|
342
|
+
suppresses client/server default scopes; omitting it preserves those defaults.
|
|
343
|
+
`baseScopes` remains mandatory and is included in every authorization request.
|
|
344
|
+
Use the explicit empty override when all requested scopes are supplied there;
|
|
345
|
+
verify the actual host authorization request after updating its package.
|
|
346
|
+
|
|
347
|
+
`review.test_cases` must contain exactly five `positive` and three `negative`
|
|
348
|
+
cases. Every case needs `description` and `prompt`; positive cases also need
|
|
349
|
+
`tools_triggered` (comma-separated actual `task_*` names) and
|
|
350
|
+
`expected_behavior`. Optional `file_attachment_urls` and `expected_output_url`
|
|
351
|
+
must be public HTTPS URLs. `review.demo_recording_url` must identify the actual
|
|
352
|
+
accessible walkthrough; it may include a video query string. Supply
|
|
353
|
+
`publication.release_notes`. The builder emits review beside `interface` under
|
|
354
|
+
`extensions.com.openai`, and auth under the MCP server's
|
|
355
|
+
`extensions.com.openai.auth`. Missing fields stop public preflight. Internal
|
|
356
|
+
fixtures may omit the three inputs; supplied inputs are still validated. A
|
|
357
|
+
correct metadata shape does not prove its cases ran or qualify the release.
|
|
358
|
+
|
|
359
|
+
Optional `listing: { longDescription, category }` replaces those two directory
|
|
360
|
+
fields through the same builder. Describe the intended users and actual access
|
|
361
|
+
limitations; use an exact category title from the publisher dashboard (for this
|
|
362
|
+
repository workflow, `Developer Tools`). Descriptions allow up to 4000 characters
|
|
363
|
+
and line breaks. Category titles must be one line of at most 80 characters.
|
|
364
|
+
Unknown fields, credentials, blank values and unsupported controls are rejected.
|
|
365
|
+
Identity, publisher, review inputs and release gates cannot be overridden here.
|
|
366
|
+
Keep final listing copy in the package config rather than editing a generated ZIP.
|
|
367
|
+
See [OpenAI listing metadata](https://developers.openai.com/plugins/deploy/submission#listing-metadata).
|
|
368
|
+
|
|
369
|
+
For a disposable sandbox portal draft, internal builds can set
|
|
370
|
+
`developmentIdentity: { name: "aport-task-delivery-preview", displayName:
|
|
371
|
+
"APort Tasks Preview" }`. This prevents a sandbox connection from occupying the
|
|
372
|
+
canonical directory identity: changing a registered MCP server URL later is not
|
|
373
|
+
a self-service update. Public validation refuses this input; use the canonical
|
|
374
|
+
identity and permanent production endpoint for the actual release.
|
|
375
|
+
|
|
376
|
+
The vendored portable MCP schema predates this OpenAI authentication extension.
|
|
377
|
+
Validation retains the original schema bytes and adds only the documented,
|
|
378
|
+
strictly validated auth overlay. The release manifest records its separate
|
|
379
|
+
`submissionSchemaSha256`. Do not hand-edit the emitted ZIP to add metadata or
|
|
380
|
+
weaken the portable schema to admit arbitrary server fields. Reviewer credentials
|
|
381
|
+
and private reviewer instructions are rejected; enter them only in the portal.
|
|
382
|
+
|
|
383
|
+
The configuration shape is:
|
|
384
|
+
|
|
385
|
+
```json
|
|
386
|
+
{
|
|
387
|
+
"publisher": "APort",
|
|
388
|
+
"endpoint": "https://aport.io/api/task-delivery/mcp",
|
|
389
|
+
"fixture": false,
|
|
390
|
+
"supportEmail": "<owner-selected support email>",
|
|
391
|
+
"homepage": "<owner-selected HTTPS product URL>",
|
|
392
|
+
"supportUrl": "<owner-selected HTTPS support URL>",
|
|
393
|
+
"privacyUrl": "<owner-selected HTTPS privacy URL>",
|
|
394
|
+
"termsUrl": "<owner-selected HTTPS terms URL>",
|
|
395
|
+
"licenseUrl": "<owner-selected HTTPS license URL>",
|
|
396
|
+
"resource": {
|
|
397
|
+
"uri": "ui://task-delivery/app",
|
|
398
|
+
"domain": "https://aport.io",
|
|
399
|
+
"connectDomains": ["https://aport.io"],
|
|
400
|
+
"resourceDomains": []
|
|
401
|
+
},
|
|
402
|
+
"assets": {
|
|
403
|
+
"ui": "/private/aport-ui/task-delivery.html",
|
|
404
|
+
"icon": "/private/aport-ui/icon.png",
|
|
405
|
+
"screenshots": ["/private/aport-ui/actual-host.png"]
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
Replace every placeholder and bind the actual built UI's exact origins. This
|
|
411
|
+
shape alone does not prove deployment or supply final assets. Public packaging
|
|
412
|
+
also requires a clean source payload and verifies the requested source commit
|
|
413
|
+
against HEAD. Internal dirty builds record their changed payload files and hashes.
|
|
414
|
+
|
|
415
|
+
Public validation refuses absent metadata, example URLs, unavailable built UI,
|
|
416
|
+
fixture assets and missing screenshots with remedies. A structurally valid
|
|
417
|
+
package remains `public-candidate-unqualified`, never submission-ready by itself.
|
|
418
|
+
Rebuild executable/configuration changes and invalidate affected evidence.
|
|
419
|
+
|
|
420
|
+
Official formats rechecked 2026-10-12: [portable packaging](https://developers.openai.com/plugins/build/plugins),
|
|
421
|
+
[UI resources](https://developers.openai.com/plugins/build/chatgpt-ui),
|
|
422
|
+
[global/thread entrypoints](https://developers.openai.com/plugins/build/extensions),
|
|
423
|
+
[submission](https://developers.openai.com/plugins/deploy/submission).
|
|
424
|
+
Vendored portable JSON schemas retain their source URLs and recorded hashes.
|
|
425
|
+
|
|
426
|
+
## APort reference integration: M6 handoff gates
|
|
427
|
+
|
|
428
|
+
These gates belong to the APort integration handoff. M5 artifact tests are
|
|
429
|
+
deterministic and unpaid; they are not actual host evidence.
|
|
430
|
+
M6 pins the **human-merged** artifact/digest into the existing APort job, verifies
|
|
431
|
+
real Pages/runtime/bindings/durable storage, and reconciles PR #414's deployment.
|
|
432
|
+
The 2026-10-07 endpoint probe returned HTTP 503. That audit session had no configured
|
|
433
|
+
Agents API credential/model/environment; pinned Cloud listing was accessible but
|
|
434
|
+
proved neither environment repository nor inference access. Browser/capture
|
|
435
|
+
inventory was available, with no task-delivery tool installed in that session.
|
|
436
|
+
|
|
437
|
+
Mandatory remaining gates: actual endpoint OAuth discovery/tool scans and scoped
|
|
438
|
+
account isolation; both providers' real implementation and correction PRs across
|
|
439
|
+
restart; public Cloud mode only if delegation is demonstrated (otherwise trusted
|
|
440
|
+
operator mode); actual sidebar/panel and fresh-account reconnect; restricted
|
|
441
|
+
reviewer account with shared campaign allowance; authentic screenshots/demo;
|
|
442
|
+
working legal/support pages; eligible publisher project/org/domain verification;
|
|
443
|
+
bounded G9 kit with five positive/three negative cases. APort is publisher. No
|
|
444
|
+
release approval, submission, deployment or publication is claimed by M5.
|
|
445
|
+
|
|
446
|
+
### Model-visible discovery and evidence
|
|
447
|
+
|
|
448
|
+
`list` accepts an optional saved task ID as `cursor`, returns at most 100 authorized
|
|
449
|
+
tasks in ID order, and supplies `nextCursor` when `truncated` is true. Every page
|
|
450
|
+
uses current account and repository authorization; a cursor grants no access.
|
|
451
|
+
MCP evidence responses expose bounded artifact IDs/hashes, provider test claims,
|
|
452
|
+
coordinator verification observations and the PR link. Log responses expose the
|
|
453
|
+
saved window range, count, gap and `nextAfter`, while raw log text and briefs remain
|
|
454
|
+
in authorized UI metadata. Neither read operation starts provider reconciliation.
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
CLI task mutations serialize with runtime backup and migration using the task mutation owner, while ordinary daemon operation remains available. A namespace containing `runtime-pin.json` requires the manifest-aware delivery adapter for writes; the CLI can still list and inspect it. Keep ordinary CLI tasks in an unpinned local home. Package output directories must be outside the package source root, including destinations reached through symlinked parents.
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
First-time runtime pinning requires an idle legacy namespace; retain the original runtime until active intake and execution are drained. All CLI registry mutations, chain writes and control requests share maintenance exclusion, including local web control requests. Pinned namespaces require the manifest-aware adapter.
|
|
461
|
+
|
|
462
|
+
The filesystem delivery adapter admits at most 256 ordinary operation identities per account scope and caps their serialized store section at 32 MiB. At the operation-count limit, retained operation IDs remain available for idempotent retries; new ordinary operations fail with `DELIVERY_CAPACITY` before task effects. Keep old namespaces for retries, drain their active work and archive them before provisioning a separate namespace for new work. Never route retries to a new namespace or delete receipts to free capacity. A size-limit failure during acknowledgement preserves the durable intent; inspect and reconcile that operation before authorizing another identity. Oversized legacy stores require an operator-managed archival/indexed-store migration that preserves identities; files exceeding the combined byte ceiling are refused before loading into memory.
|
|
463
|
+
|
|
464
|
+
Cancellation uses a separate 1 MiB reserve of at most 256 compact receipts, one per retained task. Ordinary receipts retain their 256-ID and 32 MiB limits. Cancel retries retain the original operation ID and signature, reauthorize, and return the current task view; they do not retain another full snapshot. A new cancellation identity for an already reserved task is refused with instructions to retry its original ID or inspect its status. This reserve cannot be consumed by other controls, and lost scheduling acknowledgements remain retryable without repeating cancellation effects.
|
|
465
|
+
|
|
466
|
+
New ordinary receipts reserve 4 KiB for the compact acknowledgement and bounded task/repository binding before any task effects. Acknowledgements retain operation signatures and task identity, not full task-view snapshots; retries reauthorize and return the current task view without repeating effects. Historical acknowledged snapshots remain replayable. Historical pending intents must pass the same reservation check before recovery. List model responses contain task/repository identity, status and question count; inspect and mutation responses retain question text.
|
|
467
|
+
|
|
468
|
+
Interrupted resume, validation and start requests whose intake revision has advanced are settled from the current saved task view, including blocked or incomplete outcomes. Exact retries do not repeat their effects or infer approval from a later revision. Further recovery requires inspection and a new operation against that revision; unresolved intake or execution state continues to pin its artifact independently of the settled delivery receipt.
|
|
469
|
+
|
|
470
|
+
Public packaging rechecks HEAD and payload changes after npm packing. A changed checkout or failed Git recheck removes the staged output and requires a rebuild; internal fixtures record late payload changes or loss of source verification without claiming release qualification.
|
|
471
|
+
|
|
472
|
+
Archive payload hashes are computed from packed entries and checked against the selected Git commit. The bundled parser is bound by `templates/plugin/bundled-runtime.json`, whose file hashes and lock integrity must be refreshed and committed together when upgrading that dependency. Before/after Git status remains an additional check, not byte provenance.
|
|
473
|
+
|
|
474
|
+
New delivery intents fence later ordinary mutations until the original operation settles; cancellation retains its independent reserve. This prevents unrelated revision changes from being accepted as an interrupted operation's outcome. Legacy intents without this fence cannot use revision-only recovery and remain explicit reconciliation obligations.
|
|
475
|
+
|
|
476
|
+
Explicit task-service refusals proven to precede effects are stored as compact acknowledged rejection receipts. Exact retries replay the bounded redacted code/message; corrected requests use a new identity and current revision. Unknown failures keep their intent and mutation fence rather than being classified as safe from an unchanged revision alone.
|