@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
package/docs/prd.md
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# The PRD contract
|
|
2
|
+
|
|
3
|
+
Repository review lessons are advisory shared inputs. They cannot rewrite this
|
|
4
|
+
contract, its Verify commands, acceptance criteria or APort completion gates.
|
|
5
|
+
Candidate/repository instructions are not learning approval authority. See
|
|
6
|
+
[learning](learning.md) for exact revision review, signed activation and the
|
|
7
|
+
collection-only qualification status; an incomplete implementation receipt must
|
|
8
|
+
keep unmet criteria false.
|
|
9
|
+
|
|
10
|
+
A PRD is the structured brief for one repository deliverable. Write it yourself,
|
|
11
|
+
or let [natural-language intake](tasks.md) prepare it from a request. Both paths
|
|
12
|
+
must pass the same rules before implementation; there is no validation override.
|
|
13
|
+
The agent also receives the repository and any explicitly selected source files,
|
|
14
|
+
permissions and review feedback.
|
|
15
|
+
|
|
16
|
+
The deliverable need not be code. A research report, documentation update or
|
|
17
|
+
content package can use this contract when its outputs live in the repository.
|
|
18
|
+
For example, specify a report with cited sources, a fixed comparison table and
|
|
19
|
+
no changes to existing code. Verify its required files/schema/link checks using
|
|
20
|
+
commands the repository actually provides, plus `git diff --check`. Formatting
|
|
21
|
+
checks alone do not prove research accuracy; acceptance evidence and review still
|
|
22
|
+
need to establish the requested outcome. Account operations, publishing to an
|
|
23
|
+
external service and deployments are not implied by a repository task.
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
gallivant new widget-export # from anywhere inside the repo the work belongs to
|
|
27
|
+
# write it
|
|
28
|
+
gallivant ready path/to/repo/docs/prds/widget-export.md --check # the checklist, nothing written
|
|
29
|
+
gallivant ready path/to/repo/docs/prds/widget-export.md # records readiness and updates the file; does not commit
|
|
30
|
+
gallivant start path/to/repo/docs/prds/widget-export.md
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## The rules
|
|
34
|
+
|
|
35
|
+
| Rule | Passes when |
|
|
36
|
+
|---|---|
|
|
37
|
+
| path | The file is `docs/prds/<id>.md` in the target repo, `<id>` lowercase letters, digits and dashes. New runs use branch `work/<id>`; existing legacy branches remain readable. |
|
|
38
|
+
| frontmatter | A `---` block with `status: draft` or `ready`. If supplied, `harness` must be a registered ID; omission uses `claude`. Set it explicitly to make the runtime choice clear. Registration does not guarantee dispatch availability; see [support](../README.md#harness-support). |
|
|
39
|
+
| title | Exactly one H1, 8 to 80 characters. It supplies the PR title, subject to public-output validation. |
|
|
40
|
+
| problem | `## Problem` has at least 40 words. Who hurts, when, and what changes when this ships. |
|
|
41
|
+
| stories | Every bullet under `## User stories` reads `As a <who>, I want <what>, so that <why>`. At least one. |
|
|
42
|
+
| criteria | Every bullet under `## Acceptance criteria` contains Given, When and Then. At least one per user story. A criterion may run over indented continuation lines. |
|
|
43
|
+
| verify | `## Verify` lists at least one command, in backticks or a code block, that the session must run green before opening the PR. No `sudo`, no `rm -rf`, no piped installers. |
|
|
44
|
+
| look | `## Where to look` names files or directories to start from, or a single bullet `none`. |
|
|
45
|
+
| scope | `## Out of scope` has at least one bullet. |
|
|
46
|
+
| placeholders | No `TODO`, `TBD`, `FIXME`, `???`, `lorem ipsum` or unfinished `<angle-bracket>` placeholders in the body. Recognized inline HTML tags are allowed. Replace every template placeholder. |
|
|
47
|
+
| size | At most 1,500 body words. A PRD is one pull request. Split anything bigger. |
|
|
48
|
+
| sources | Every file named in `sources` exists, is readable text, and is inside the repository. Only checked on a brief that names any. |
|
|
49
|
+
|
|
50
|
+
`ready --check` prints every rule with ok or FAIL and, for a failure, what to change. `start` runs the same checks again and refuses a brief with any failing rule, so editing a PRD after marking it ready cannot sneak a bad one through.
|
|
51
|
+
|
|
52
|
+
## Optional frontmatter
|
|
53
|
+
|
|
54
|
+
These keys beyond `status` and `harness` are read if present:
|
|
55
|
+
|
|
56
|
+
- `aport_decision` is written by `gallivant ready`, the receipt of the decision that made the PRD ready. It is not
|
|
57
|
+
part of the rules.
|
|
58
|
+
- `sources` names files beside this brief that travel into the session's checkout, so a brief can cite a requirements
|
|
59
|
+
document or an `AGENTS.md` that only exists in your own tree. Paths are relative to the repository root, named one
|
|
60
|
+
at a time:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
---
|
|
64
|
+
status: ready
|
|
65
|
+
harness: codex
|
|
66
|
+
sources:
|
|
67
|
+
- docs/research-notes.md
|
|
68
|
+
- AGENTS.md
|
|
69
|
+
---
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Absolute paths, `..` segments, globs, directories, backslashes, `.git` components and symlinks at any path component
|
|
73
|
+
are refused. Files are checked on both reading and copying into the checkout. `gallivant ready` reads every file, so a
|
|
74
|
+
mistyped path is refused at your terminal rather than thirty minutes into a paid run. Each file is snapshotted
|
|
75
|
+
beside the brief and written into the checkout from that snapshot, so a session cannot widen what it was given by
|
|
76
|
+
editing a document it was handed, and the list is part of the contract: adding or removing a file stops the entry
|
|
77
|
+
the way an edited criterion does. See [config.md](config.md#files-a-brief-carries-sources) for how it differs from
|
|
78
|
+
`context_paths`.
|
|
79
|
+
- `context_paths` gives this one brief read access to directories outside its checkout, added to whatever
|
|
80
|
+
`config.json` already lists rather than replacing it. Comma-separated, or a `[a, b]` list:
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
---
|
|
84
|
+
status: ready
|
|
85
|
+
harness: claude
|
|
86
|
+
context_paths: ~/work/schemas, ~/Projects/design-system
|
|
87
|
+
---
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Every entry is held to the same refusals as the config key, so a PRD cannot grant itself `$HOME`, the Gallivant
|
|
91
|
+
home or a harness config directory. `start` fails with the offending path named and nothing is recorded. This is
|
|
92
|
+
the operator's list, not the agent's: fix rounds read the snapshot of the brief taken when the run started, so
|
|
93
|
+
editing the PRD in the checkout changes nothing about what later runs can read. See
|
|
94
|
+
[guardrails.md](guardrails.md#extra-read-directories-are-a-widening-not-a-feature) for what it costs.
|
|
95
|
+
|
|
96
|
+
## One gate, one implementation
|
|
97
|
+
|
|
98
|
+
The checker takes a Request, which is what a source produces after reading your
|
|
99
|
+
input. Its structure rules inspect that request; its `sources` rule also reads
|
|
100
|
+
the declared repository files to verify their containment, readability and text
|
|
101
|
+
format. No provider call is needed for `ready --check`.
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
{ id, repo, title, body, harness, status, source: { kind, url, author }, raw }
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The repository-file source lives under `lib/sources/prd.mjs`. It parses
|
|
108
|
+
frontmatter, takes the ID from the filename and resolves the repository.
|
|
109
|
+
Natural-language intake additionally drafts a PRD with owner requirement mappings,
|
|
110
|
+
then uses this same checker/readiness path. Intake is an implemented entry point,
|
|
111
|
+
not a second completion system. Other source proposals in `docs/prds` and
|
|
112
|
+
`docs/design` are specifications, not necessarily implemented transports.
|
|
113
|
+
|
|
114
|
+
`path` and `sources` depend on the repository-file source and declare
|
|
115
|
+
`kinds: ["prd"]`. The other ten rules apply to every Request. A future non-file
|
|
116
|
+
source would use those shared rules and explicitly implement any additional
|
|
117
|
+
source-specific checks; it would not need a separate readiness gate.
|
|
118
|
+
|
|
119
|
+
## Ready is an APort decision
|
|
120
|
+
|
|
121
|
+
`gallivant ready` records an APort decision as well as flipping the status. The PRD is treated as a deliverable under APort's `deliverable.task.complete.v1` policy: the twelve rules become the acceptance criteria of a per-PRD passport, the checker's verdict per rule becomes an attestation with evidence, the PRD text goes through the policy's output scan for placeholder text, and the summary names the PRD and its score. The built-in rules run first and list every problem; when they pass and `deliverable.evaluator` is `aport`, the same context and passport go to APort's verify endpoint, and its answer is recorded. Only an allow flips the status, and the decision id is written into the PRD's frontmatter as `aport_decision`, so a ready PRD carries the receipt of the decision that made it ready. Without a config, or with `deliverable: null`, the decision is local only. `ready` does not commit; the daemon works from its own snapshot of the PRD taken by `start`, so commit the PRD with the rest of your work whenever you like.
|
|
122
|
+
|
|
123
|
+
## Editing the brief after the work has started
|
|
124
|
+
|
|
125
|
+
`start` copies the brief into `~/.gallivant/prds/<id>.md`, and the completion gate reads only that copy. That is what
|
|
126
|
+
stops a session rewriting its own acceptance criteria. It is not what stops YOU rewriting them: the snapshot and the
|
|
127
|
+
file in your checkout are two files, and until this existed nothing compared them. A brief edited after `start` meant
|
|
128
|
+
the run finished against criteria nobody was asking for and the PR arrived satisfying a document that had changed.
|
|
129
|
+
|
|
130
|
+
So the two are compared, and what happens depends on what you changed. The comparison is in the contract's own terms:
|
|
131
|
+
the acceptance criteria, Verify commands, `harness`, `context_paths`, `sources`,
|
|
132
|
+
and the **Coordinator delivery contract** when present. The ownership section
|
|
133
|
+
keeps a natural-language publication instruction separate from provider work.
|
|
134
|
+
It is validated and fingerprinted too; malformed edits cannot be silently ignored.
|
|
135
|
+
Physical LF/CRLF formatting changes are equivalent, while the JSON-escaped original
|
|
136
|
+
request bytes remain exact.
|
|
137
|
+
|
|
138
|
+
| What you changed | What happens |
|
|
139
|
+
|---|---|
|
|
140
|
+
| Anything outside those contract fields: the Problem prose, a reworded story, a new Out of scope bullet | Nothing stops. The snapshot follows your edit so later prompts carry your current wording, the log says it happened, and you are not told. Stopping a run to ask about a typo fix would be worse than useless. |
|
|
141
|
+
| A criterion, a Verify command, the harness, `context_paths`, `sources` or coordinator delivery ownership | The entry stops with `prd-changed` before the gate runs, and `gallivant why` names each difference. |
|
|
142
|
+
| The ORDER of two criteria, without changing a word of either | Also `prd-changed`. Criteria are numbered by position, and the receipt on the open PR attests `ac-1` and `ac-2` by those numbers, so swapping two of them leaves the receipt attesting each criterion with the other's evidence. |
|
|
143
|
+
| The file no longer passes the contract | `prd-illegal`. Fix the file and `gallivant ready` it again; it cannot become the brief the gate judges as it stands. |
|
|
144
|
+
| The file is gone from your checkout | `prd-gone`. Restore it, or `gallivant remove` the entry. |
|
|
145
|
+
| Only the line endings, CRLF to LF or back | Nothing. It is the same brief, so it compares as the same brief. (`ready` used to refuse a CRLF file outright, reporting a missing frontmatter block that was right there; both halves are fixed.) |
|
|
146
|
+
|
|
147
|
+
While a `prd-changed` stop is unresolved the gate judges **neither** brief. Judging the snapshot would certify a brief
|
|
148
|
+
you have moved on from, which is the silent divergence this exists to end. Judging your new copy would certify criteria
|
|
149
|
+
the session was never given and has not attested, so the receipt on the PR would be answering a different question from
|
|
150
|
+
the one asked. There is no third brief, so no decision is made until you say which brief is the brief:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
gallivant why widget#142 # every difference, and what the gate is doing about it
|
|
154
|
+
gallivant resume widget#142 --resnapshot # the edit is the brief; the session is told what moved
|
|
155
|
+
# or put the brief back the way it was, and the next tick carries on where it left off
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`--resnapshot` is the explicit way to adopt a changed contract into an existing snapshot, and it is loud about it: a warning in
|
|
159
|
+
`errors.log` naming the file, who asked and every difference, and a resume prompt that tells the session what moved and
|
|
160
|
+
to reread the brief rather than trust what it remembers. Work already done against a criterion that has not changed
|
|
161
|
+
still stands, which is the whole reason this is a resume and not a restart.
|
|
162
|
+
|
|
163
|
+
Why a person and not the daemon. A criterion ADDED means the work in flight is valid but incomplete. A criterion
|
|
164
|
+
REWRITTEN means what was built is no longer what is wanted. From the text of two files those are the same event, and
|
|
165
|
+
guessing wrong is expensive in both directions: finish the old brief and you ship the wrong thing, restart and you throw
|
|
166
|
+
away work that may have been exactly right. So the daemon proves what it can (which criterion, which command) and puts
|
|
167
|
+
the decision in front of you.
|
|
168
|
+
|
|
169
|
+
One more signal, reported and never relied on: `gallivant ready` writes `aport_decision` into the frontmatter, so a
|
|
170
|
+
brief whose decision id has changed is one you deliberately re-blessed. `why` says so. It cannot be the test, because
|
|
171
|
+
`ready` leaves the id alone on a brief that was already ready and a hand-edit can miss the frontmatter entirely.
|
|
172
|
+
|
|
173
|
+
An entry that never saw your checkout is never stopped for this. `register` and the daemon's recovery from GitHub build
|
|
174
|
+
entries with no record of where your copy lives, so there is nothing to compare and they carry on exactly as before.
|
|
175
|
+
|
|
176
|
+
## Why this shape
|
|
177
|
+
|
|
178
|
+
- **Stories and criteria in fixed forms** give the session something to test against and give you something to review in the PR description. Free-form prose produces free-form PRs.
|
|
179
|
+
- **Verify is a command, not a sentence.** The session runs it before opening the PR, and again after every fix round. If you cannot name the command, the PRD is not ready.
|
|
180
|
+
- **Where to look** is the cheapest way to cut a session's wandering. Two paths save ten minutes of grep.
|
|
181
|
+
- **Out of scope** is what keeps a two-hour PRD from becoming a two-day refactor.
|
|
182
|
+
- **The size cap** is the review budget. Three rounds with a reviewer on a 300-line PR works; on a 3,000-line PR it does not.
|
|
183
|
+
|
|
184
|
+
## What the session receives
|
|
185
|
+
|
|
186
|
+
The session receives the full PRD as data, the branch/base, selected sources,
|
|
187
|
+
Verify commands and scope constraints. Local execution asks the agent to deliver
|
|
188
|
+
one PR without changing the base branch. Hosted execution returns artifacts;
|
|
189
|
+
the coordinator verifies and publishes them with its own GitHub credentials.
|
|
190
|
+
Review fixes return to the same session with current findings and checks. The
|
|
191
|
+
[execution guide](execution.md) describes the ownership boundaries.
|
|
192
|
+
|
|
193
|
+
## The completion receipt
|
|
194
|
+
|
|
195
|
+
Passing the contract gets a PRD started. Getting the PR to `ready-for-human` needs a second gate at the other end, shaped after APort's `deliverable.task.complete.v1` policy: the agent must attest, with evidence, that every acceptance criterion holds.
|
|
196
|
+
|
|
197
|
+
Each Acceptance criteria bullet becomes a criterion with a stable id, `ac-1`, `ac-2`, in order. The session is told, at start and on every fix round, to end the PR body with a receipt:
|
|
198
|
+
|
|
199
|
+
````markdown
|
|
200
|
+
```work-attestations
|
|
201
|
+
{
|
|
202
|
+
"task_id": "widget/widget-export",
|
|
203
|
+
"output_type": "code",
|
|
204
|
+
"summary": "What changed and how it was verified, at least 20 words.",
|
|
205
|
+
"criteria_attestations": [
|
|
206
|
+
{ "criterion_id": "ac-1", "met": true, "evidence": "src/export/csv.test.ts: 'exports three rows'" },
|
|
207
|
+
{ "criterion_id": "ac-2", "met": true, "evidence": "src/export/Button.tsx:41 disabled when empty; test 'empty state hint'" }
|
|
208
|
+
]
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
````
|
|
212
|
+
|
|
213
|
+
When checks are green and the reviewer has no blocking findings, the daemon builds the policy context and evaluates it. `tests_passing` comes from the checks the daemon observed, never from the receipt. A deny starts a fix round whose prompt carries the policy's deny codes, which are written so the agent can correct itself:
|
|
214
|
+
|
|
215
|
+
| Code | Meaning |
|
|
216
|
+
|---|---|
|
|
217
|
+
| `oap.receipt_missing` | No receipt block, not valid JSON, or a shape the rules cannot read: `criteria_attestations` not an array, or an element that is not an object carrying a `criterion_id` string. The reason says which. |
|
|
218
|
+
| `oap.criteria_incomplete` | A criterion has no attestation. |
|
|
219
|
+
| `oap.evidence_missing` | An attestation has empty evidence. |
|
|
220
|
+
| `oap.criteria_not_met` | An attestation is not `met: true` (the string `"true"` does not count). |
|
|
221
|
+
| `oap.criteria_unknown` | An attestation names an id that is not in the PRD. |
|
|
222
|
+
| `oap.summary_insufficient` | Summary under `min_summary_words`. |
|
|
223
|
+
| `oap.tests_not_passing` | Checks on the head are not all green. |
|
|
224
|
+
| `oap.blocked_pattern_detected` | The scanned output contains a blocked pattern. |
|
|
225
|
+
|
|
226
|
+
A brief with no `## Acceptance criteria` section has nothing to attest, and nothing to attest is a deny, not a pass: every criteria rule is vacuously satisfied by an empty list, so the gate would otherwise allow on the summary and the checks alone. This matters because the snapshot the gate reads is taken from the PR branch when the daemon has none, and that copy was writable by the session.
|
|
227
|
+
|
|
228
|
+
The output scan sees only the lines the diff adds, and it has to see all of them. A diff `gh pr diff` cannot return, or one at or above the 16 MiB scan cap, is no decision rather than a partial scan reported as clean. Hosted requests stay below the API body limit by splitting large output into overlapping pieces, each carrying the complete receipt, criteria and policy limits. Every piece must pass; overlap catches blocked substrings across boundaries, and no output is omitted. The local and hosted scans both match blocked patterns case-insensitively. An unreadable diff or unavailable evaluator retries without dispatching an agent or spending a round; after five consecutive failures the entry stops as `needs-human` with reason `stuck`. `status` and `why` show the completion failure instead of blaming an already-clear reviewer. Correct the cause (split a diff above the scan cap, for example), then `gallivant resume <id>`.
|
|
229
|
+
|
|
230
|
+
A round that only rewrites the receipt counts as a round: the daemon posts a marked "Completion receipt updated" comment instead of a re-review request, since no code moved, so the round count on GitHub still matches the registry. The iteration cap applies. Limits live under `deliverable` in config, in the shape of the policy's passport limits; `"deliverable": null` turns the gate off.
|
|
231
|
+
|
|
232
|
+
Who decides. The built-in rules run first and list every problem at once. When they pass and `deliverable.evaluator` is `aport` (the default), the daemon builds a per-task passport in OAP shape, with the PRD's criteria as the policy's `acceptance_criteria` limits, and posts it with the context to APort's verify endpoint for `deliverable.task.complete.v1`. APort evaluates the passport as sent and its deny wins. If APort cannot be reached there is no decision: the PR stays where it is, nothing is dispatched, no round is counted, and the daemon asks again next tick, up to the five-failure bound above. Set `deliverable.on_unreachable` to `local` to let the built-in verdict stand instead; the log then says which verdict was used. `evaluator: "local"` skips the hosted call. The API key recorded by the APort Claude install, if any, is sent so the calls count against your account; the route also works unauthenticated, rate limited per IP.
|
|
233
|
+
|
|
234
|
+
APort's deny names one problem at a time (evaluation stops at the first failing rule) and does not include the criterion id, which is why the local pass runs first.
|
|
235
|
+
|
|
236
|
+
## Provenance on a decision
|
|
237
|
+
|
|
238
|
+
Both gates send a `meta` object inside the context they already send:
|
|
239
|
+
|
|
240
|
+
```json
|
|
241
|
+
"meta": { "framework": "codex", "gallivant_version": "0.2.0" }
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
`framework` is the harness that did the work, or that the brief names for a readiness decision. `gallivant_version` is the release that asked. A machine running Claude Code and Codex against one passport otherwise produces decisions nobody can tell apart afterwards, and the OAP decision object is closed (`additionalProperties: false`), so the request context is where this belongs. No specification change was needed: the policy packs leave `additionalProperties` unset, which in JSON Schema already permits extra properties, and the hosted validator's context schemas are `.unknown(true)`. An older verifier ignores the field.
|
|
245
|
+
|
|
246
|
+
It is self-reported and it is never an authorization input. Gallivant asserts these two values and nothing verifies them, so a field the caller controls could be forged the moment anything read it back to decide something. It is recorded for audit and analytics, and the local rules ignore it entirely; a test asserts that a forged `meta` changes no verdict in either direction.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Harness-independent preparation
|
|
2
|
+
|
|
3
|
+
Natural-language intake is a normal harness job with limited authority:
|
|
4
|
+
|
|
5
|
+
`request + selected context → selected harness → structured draft → Gallivant validation/ready → authorized implementation → review`
|
|
6
|
+
|
|
7
|
+
Questions and validation repairs return through that same adapter and durable
|
|
8
|
+
runner. Gallivant owns requirements, revisions, readiness and execution consent.
|
|
9
|
+
The model does not certify its own PRD or launch implementation while drafting.
|
|
10
|
+
Embedding hosts, including the APort reference integration, call these shared
|
|
11
|
+
task operations rather than recreate PRD generation or provider dispatch.
|
|
12
|
+
Preparation and implementation are separate capabilities:
|
|
13
|
+
|
|
14
|
+
| Provider | Natural-language preparation | Implementation |
|
|
15
|
+
| --- | --- | --- |
|
|
16
|
+
| Claude Code | Tools disabled | Local checkout |
|
|
17
|
+
| Codex | Isolated native profile, Codex 0.160.0+ | Local checkout |
|
|
18
|
+
| OpenAI Agents API | Text only, no tools or environment | Hosted sandbox |
|
|
19
|
+
| Gemini CLI, OpenCode, Goose | Unavailable; use `new` → `ready` → `start` | Local checkout |
|
|
20
|
+
| Codex Cloud | Unavailable | New dispatch blocked on environment/repository verification |
|
|
21
|
+
|
|
22
|
+
An adapter's presence does not prove the configured account can use its selected
|
|
23
|
+
model. Check [local live evidence](https://github.com/uchibeke/gallivant/blob/main/docs/audit/harness-live-validation.md),
|
|
24
|
+
[Agents setup](openai-agents.md) and the [Cloud blocker](codex-cloud.md).
|
|
25
|
+
Preparation consumes inference, but grants no implementation consent. Selected
|
|
26
|
+
repository text is context; it cannot authorize tools or publication.
|
|
27
|
+
|
|
28
|
+
The canonical adapter registry owns preparation boundaries. Claude uses its
|
|
29
|
+
tools-off mode. Codex 0.160.0 uses an isolated permission profile, no approvals,
|
|
30
|
+
disabled command network, no shell/browser/apps/plugins/hooks/delegation tools,
|
|
31
|
+
and explicit disabling of every inherited MCP server. An empty MCP table alone
|
|
32
|
+
does not remove inherited entries. Both `agents.enabled` and
|
|
33
|
+
`features.multi_agent_v2` are disabled: a model-selected V2 delegation capability
|
|
34
|
+
can override the V1 `features.multi_agent` switch. Some model catalogs still
|
|
35
|
+
expose apply_patch; the sandbox denies its file access. No preparation tool receives project or
|
|
36
|
+
credential filesystem grants. Selected source text is supplied in the prompt.
|
|
37
|
+
|
|
38
|
+
The following isolation details apply to local Codex preparation. Agents API
|
|
39
|
+
preparation instead sets `environment: {type: "none"}`, `tools: []` and
|
|
40
|
+
`multi_agent.enabled: false` on session creation, verifies the effective session,
|
|
41
|
+
and accepts only the owned root turn's final text. It sends no local filesystem,
|
|
42
|
+
GitHub or implementation credentials. Unsupported effective configuration or tool
|
|
43
|
+
output fails closed; [the managed transport](openai-agents.md#task-and-command-use)
|
|
44
|
+
records its recovery and live qualification limits.
|
|
45
|
+
|
|
46
|
+
The Codex task-private config snapshot is parsed with bundled smol-toml. Model and
|
|
47
|
+
provider settings are retained; legacy sandbox settings are removed because they
|
|
48
|
+
override permission profiles. Legacy `notify` commands are removed from the private
|
|
49
|
+
snapshot and disabled explicitly; turning off hooks alone does not disable them.
|
|
50
|
+
Inherited `instructions`, `developer_instructions`, `compact_prompt`,
|
|
51
|
+
`model_instructions_file` and `experimental_compact_prompt_file` are removed from
|
|
52
|
+
the private snapshot. Codex reads these itself, outside tool permissions. Automatic
|
|
53
|
+
skill instructions, bundled/cloud skills, memory usage/generation and token-budget
|
|
54
|
+
compaction overrides are disabled. Stale `AGENTS.md` and `AGENTS.override.md` in the
|
|
55
|
+
private Codex home are unlinked: global instructions ignore `project_doc_max_bytes`.
|
|
56
|
+
The operator's own AGENTS files are never copied or changed.
|
|
57
|
+
|
|
58
|
+
Native telemetry exporters, prompt logging and analytics/feedback are disabled.
|
|
59
|
+
Private `log_dir` and `sqlite_home` overrides are removed so draft logs/state stay
|
|
60
|
+
under the private home; inherited hooks and notifications remain disabled.
|
|
61
|
+
Before any drafting turn, a bounded native `config/read` **and**
|
|
62
|
+
`configRequirements/read` probe verifies merged settings and separate managed
|
|
63
|
+
requirements. The latter can inject developer instructions or force runtime
|
|
64
|
+
permission/approval/web-search fallbacks absent from the raw config. Both reads
|
|
65
|
+
share one timeout, cancellation handler and output bound. They start no model
|
|
66
|
+
turn, send no intake text and discard configuration diagnostics. Conflicting
|
|
67
|
+
context, telemetry, storage, sandbox, tool, notification, MCP or permission settings fail closed before a
|
|
68
|
+
preparation receipt is returned. Managed policy is never rewritten to obtain a pass.
|
|
69
|
+
Native operator files and managed requirements are unchanged.
|
|
70
|
+
Unsupported named config profiles and ambiguous MCP server names stop
|
|
71
|
+
before drafting with an actionable error. Implementation argv is unchanged.
|
|
72
|
+
|
|
73
|
+
Run the ordinary suite with `npm ci && npm test`. To verify the installed Codex
|
|
74
|
+
against a local Responses fixture without buying inference:
|
|
75
|
+
|
|
76
|
+
```sh
|
|
77
|
+
node test/preparation-codex-native.mjs /absolute/path/to/codex \
|
|
78
|
+
/path/to/models_cache.json gpt-6.1-sol gpt-6-astra gpt-5.5
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The native fixture explicitly loads the supplied model catalog, including its
|
|
82
|
+
delegation version. It attempts shell, inherited MCP, delegation and file-patch
|
|
83
|
+
calls both inside and outside the workspace. It seeds file and inline instructions,
|
|
84
|
+
project/global AGENTS, skill metadata, memory, notifications, telemetry and external
|
|
85
|
+
state paths. Every provider request is checked for sentinel context. Model choice
|
|
86
|
+
and reasoning effort must survive, and external writes/telemetry must stay absent.
|
|
87
|
+
On 2026-10-07, all three models passed these checks with Codex 0.160.0, including
|
|
88
|
+
Sol and Astra with explicit V2 catalog metadata. Inherited notification commands
|
|
89
|
+
stayed disabled and unselected instruction text was absent from every request.
|
|
90
|
+
Conflicting effective settings were refused before any model request. Managed precedence is covered
|
|
91
|
+
by protocol regression fixtures, including separate instruction requirements and
|
|
92
|
+
permission fallbacks, without editing the machine's administrator policy.
|
|
93
|
+
This proves native CLI/configuration behavior with a fixture provider,
|
|
94
|
+
not live provider eligibility or a completed APort/ChatGPT workflow.
|
|
95
|
+
|
|
96
|
+
The [PR #10 context and side-effect audit](https://github.com/uchibeke/gallivant/blob/main/docs/audit/preparation-context-boundary.md)
|
|
97
|
+
records the source-backed findings, regression coverage and trust limits.
|
|
98
|
+
|
|
99
|
+
Official configuration references:
|
|
100
|
+
[permissions](https://learn.chatgpt.com/docs/permissions),
|
|
101
|
+
[configuration](https://learn.chatgpt.com/docs/config-file/config-reference).
|
|
102
|
+
Re-run native qualification when upgrading the CLI or adding tool capabilities.
|
|
103
|
+
|
|
104
|
+
The recorded cross-repository integration handoff names
|
|
105
|
+
[`aporthq/agent-passport#417`](https://github.com/aporthq/agent-passport/pull/417),
|
|
106
|
+
with job identity `aporthq/agent-passport/aport-task-delivery-workflow-integration`.
|
|
107
|
+
The handoff calls for reusing that continuation after the actual portable package
|
|
108
|
+
is available. This document qualifies the preparation boundary; it does not
|
|
109
|
+
establish the current deployment state of APort or a completed connected workflow.
|
|
110
|
+
Check the linked integration's release evidence separately.
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# Release qualification
|
|
2
|
+
|
|
3
|
+
The release command extends the existing package builder and its runtime recipe.
|
|
4
|
+
It does not run a second coordinator, deploy, submit, or purchase anything. A
|
|
5
|
+
regular review PR is not release completion. Missing live evidence remains
|
|
6
|
+
`needs-human`; offline success cannot satisfy the live criteria.
|
|
7
|
+
|
|
8
|
+
Run these commands from the exact source checkout after `npm ci --ignore-scripts`.
|
|
9
|
+
Use a single empty output directory outside that checkout, conventionally
|
|
10
|
+
`$RELEASE_DIR` ending in `release/aport-context`. Keep operator configuration,
|
|
11
|
+
credentials, the shared campaign ledger and private reviewer instructions outside
|
|
12
|
+
Git and outside that directory. The public package configuration is the existing
|
|
13
|
+
[package configuration](task-delivery.md), including real UI/assets, OAuth,
|
|
14
|
+
APort metadata, exactly five positive and three negative review scenarios, and
|
|
15
|
+
the accessible actual demo recording URL. Do not substitute generated images.
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
npm run release:preflight -- --config "$PACKAGE_CONFIG" --setup "$SETUP_EVIDENCE"
|
|
19
|
+
npm run release:package -- --config "$PACKAGE_CONFIG" --out "$RELEASE_DIR" --core-version 0.2.0 --source-commit "$SOURCE_COMMIT" --deployment "$DEPLOYMENT_RECORD" --evidence "$LIVE_EVIDENCE"
|
|
20
|
+
npm run release:validate -- --out "$RELEASE_DIR"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Preflight accepts only `target`, `providerAccess`, `repositoryAccess`,
|
|
24
|
+
`reviewerAccess` and `executionAllowance` evidence pointers in the setup JSON.
|
|
25
|
+
These pointers document operator checks; presence is not model-access proof.
|
|
26
|
+
Known target/domain and the existing shared USD 10 authority must not be reported
|
|
27
|
+
as unknown. Missing reservation/account/model/reviewer configuration is a concrete
|
|
28
|
+
remaining prerequisite. Resolve each returned next step before dependent actions.
|
|
29
|
+
Preflight success is `prepared-unqualified`, never submission readiness.
|
|
30
|
+
|
|
31
|
+
Deployment JSON has exactly `revision`, `configurationSha256` and `endpoint`.
|
|
32
|
+
Use the observed revision, SHA-256 of the canonical non-secret deployment
|
|
33
|
+
configuration, and `https://aport.io/api/task-delivery/mcp`. A dummy revision does
|
|
34
|
+
not establish deployment. Reuse APort's Pages endpoint, OAuth and shared `/web`
|
|
35
|
+
UI, with the existing authenticated binding to the supported durable Node runtime.
|
|
36
|
+
The deployment operator must record single-owner, restart, health, quota and
|
|
37
|
+
credential observations. Do not provision new hosting to fill missing evidence.
|
|
38
|
+
|
|
39
|
+
The builder emits the original combined ZIP, npm runtime tarball, runtime recipe,
|
|
40
|
+
operation schemas and hash manifest, plus START-HERE, listing, release notes,
|
|
41
|
+
review cases, evidence and qualification records. Screenshots remain in the
|
|
42
|
+
plugin assets and the demo URL in its review metadata. Records never enter the
|
|
43
|
+
public ZIP. The builder refuses occupied output and cleans up its own failed
|
|
44
|
+
assembly. `--internal` is only for deterministic fixture artifacts, which can
|
|
45
|
+
never qualify even if supplied with passing records.
|
|
46
|
+
|
|
47
|
+
## Evidence and invalidation
|
|
48
|
+
|
|
49
|
+
`evidence.json` has version `1`, `checks`, and optional `states`. The authoritative
|
|
50
|
+
case list, dependencies and remedies are exported as `RELEASE_CHECKS` from
|
|
51
|
+
`lib/release_package.mjs`. Each check records `kind` (`live`, `offline`, `fixture`),
|
|
52
|
+
`status` (`passed`, `failed`, `blocked`, `unverified`), `at` (observed timestamp),
|
|
53
|
+
`bindings` and `observations`. Bindings copy only that check's required core,
|
|
54
|
+
tools, plugin and deployment digests from `qualification.json.identity`.
|
|
55
|
+
Observations map every required case to a concrete run record, test output,
|
|
56
|
+
artifact or capture pointer. Keep those underlying records accessible to the
|
|
57
|
+
reviewer. This validator checks consistency and completeness of recorded evidence;
|
|
58
|
+
it cannot authenticate a narrated observation or replace actually performing it.
|
|
59
|
+
Never manufacture a record to make a gate pass.
|
|
60
|
+
Current, correctly bound live `failed` and `blocked` outcomes retain those statuses
|
|
61
|
+
in checks and blockers, even if the attempt stopped before collecting every case.
|
|
62
|
+
Outdated bindings remain `stale`; fixture, offline and future observations remain
|
|
63
|
+
`unverified`.
|
|
64
|
+
|
|
65
|
+
Core hashes cover the packed bytes and lock; tool hashes cover operations and
|
|
66
|
+
schemas; plugin hashes cover exact ZIP bytes; deployment hashes cover revision,
|
|
67
|
+
configuration, endpoint and the runtime's resource settings, requirements, exports
|
|
68
|
+
and contract versions. Resource URI/domain/CSP changes therefore invalidate every
|
|
69
|
+
deployment-dependent check even when the archive, ZIP and deployment record are
|
|
70
|
+
unchanged. Runtime serialization and source-provenance-only changes do not alter
|
|
71
|
+
this canonical configuration identity. Payload validation also checks that these
|
|
72
|
+
settings match the hashed `runtime.json`. Records using the earlier deployment digest
|
|
73
|
+
must be requalified; the independent integration check remains reusable.
|
|
74
|
+
An affected binding becomes `stale` and appears in
|
|
75
|
+
`rerun`; independent checks remain reusable. Validation also rehashes archives,
|
|
76
|
+
source payload files and the current tracked payload inventory. New, removed,
|
|
77
|
+
modified or uncommitted executable/packaging inputs require a rebuild. Audit-only
|
|
78
|
+
record changes outside the package payload do not invalidate unchanged artifacts.
|
|
79
|
+
The builder records `packagingControlHashes` for committed root and relevant nested
|
|
80
|
+
`.npmignore`, `.gitignore` and `.npmrc` files. Only paths and hashes are emitted;
|
|
81
|
+
control contents are excluded from the runtime payload. Validation compares the
|
|
82
|
+
committed inventory and checkout bytes, so clean committed additions, removals and
|
|
83
|
+
edits require rebuilding too. These inputs bind core evidence. Older manifests
|
|
84
|
+
without an inventory require rebuilding; unrelated audit-only commits remain valid.
|
|
85
|
+
The manifest also records `handoffHashes` for listing, release notes, review cases,
|
|
86
|
+
START-HERE and RUNTIME. Validation rehashes those files and the staged plugin files
|
|
87
|
+
using the builder's `assetHashes`. Older manifests without complete handoff hashes
|
|
88
|
+
require rebuilding. Treat the manifest as the immutable trust anchor; only
|
|
89
|
+
`evidence.json` and `qualification.json` are intentionally mutable release records.
|
|
90
|
+
START-HERE and the default release notes contain stable instructions, not a saved
|
|
91
|
+
readiness verdict or blocker list. Run `release:validate` after evidence updates
|
|
92
|
+
and before handoff; its returned `status`, `checks`, `blockers`, `rerun` and `states`
|
|
93
|
+
reflect current evidence. Validation does not rewrite `qualification.json`.
|
|
94
|
+
The saved qualification results and `manifest.release.states` describe assembly
|
|
95
|
+
time; the validator reads the saved deployment but recomputes qualification.
|
|
96
|
+
|
|
97
|
+
`codeMerged`, `submitted`, `approved` and `published` each require their own
|
|
98
|
+
`{at, pointer, identity}` record. `liveQualified` and `submissionReady` are derived
|
|
99
|
+
separately. Neither qualification nor a passing scan implies submission, approval
|
|
100
|
+
or publication. Missing publisher or domain prerequisites block readiness.
|
|
101
|
+
|
|
102
|
+
## Live and host verification
|
|
103
|
+
|
|
104
|
+
The existing G8 scripts own task dispatch and correction. Use their documented
|
|
105
|
+
private configurations and the **same** campaign ledger, reconcile previous
|
|
106
|
+
reservations and unknown usage first, and preserve task/session/PR identities.
|
|
107
|
+
The current Cloud adapter refuses new dispatch until its supported
|
|
108
|
+
repository-to-environment check can be demonstrated. Do not work around that gate.
|
|
109
|
+
For a live campaign, resolve and record the absolute worker-binary path on
|
|
110
|
+
the host that will execute it. Verify the selected version, architecture and
|
|
111
|
+
account; do not assume the shell `PATH` selects the intended installation.
|
|
112
|
+
Neither help nor login status qualifies inference.
|
|
113
|
+
|
|
114
|
+
```sh
|
|
115
|
+
npm run test:release:live -- --out "$RELEASE_DIR" --backend openai-agents --phase preflight
|
|
116
|
+
npm run test:release:live -- --out "$RELEASE_DIR" --backend openai-agents --phase implementation --execute
|
|
117
|
+
npm run test:release:live -- --out "$RELEASE_DIR" --backend openai-agents --phase correction --execute
|
|
118
|
+
npm run test:release:live -- --out "$RELEASE_DIR" --backend codex-cloud --phase preflight
|
|
119
|
+
npm run test:release:live -- --out "$RELEASE_DIR" --backend codex-cloud --phase implementation --execute
|
|
120
|
+
npm run test:release:live -- --out "$RELEASE_DIR" --backend codex-cloud --phase correction --execute
|
|
121
|
+
npm run test:release:host -- --out "$RELEASE_DIR"
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Paid phases require bound integration and human-approved deployment evidence.
|
|
125
|
+
Run sequentially, once per required phase. Preserve failed/unknown intent and
|
|
126
|
+
reconcile it instead of redispatching. Record provider usage or explicit unknowns;
|
|
127
|
+
unknown spend cannot be silently deducted as zero. These commands run from the
|
|
128
|
+
source checkout; G8 test drivers are not installed runtime exports.
|
|
129
|
+
|
|
130
|
+
The host command is explicitly **record validation**, not browser automation or
|
|
131
|
+
an installed-host test. Before supplying its evidence, use the actual ChatGPT host
|
|
132
|
+
with the exact candidate, a fresh account and the restricted sample repository.
|
|
133
|
+
Exercise questions, requirements, real readiness, available remote harness,
|
|
134
|
+
implementation, progress, files, PR, correction and same-task reconnect through
|
|
135
|
+
the supported sidebar/panel surfaces. Capture authentic screenshots and video.
|
|
136
|
+
Test cross-account access, expired auth, stale revisions, duplicate start, provider
|
|
137
|
+
outage and unsupported cancellation in that isolated live environment. Reopen the
|
|
138
|
+
conversation and verify saved task identity rather than rebuilding chat history.
|
|
139
|
+
A preview connection or old deployment observation cannot certify this candidate.
|
|
140
|
+
|
|
141
|
+
## Integration dependency
|
|
142
|
+
|
|
143
|
+
First inspect the existing `aporthq/agent-passport/aport-task-delivery-mcp` job
|
|
144
|
+
and PR #414. The 2026-10-18 registry observation was `done`; do not resume it.
|
|
145
|
+
PR #425 also merged to staging and must be reconciled to avoid duplicating its
|
|
146
|
+
connected-runtime work. M5 PR #12 merged; rebuild the actual selected artifact
|
|
147
|
+
and pin its digest before preparing a continuation. Carry the merged
|
|
148
|
+
`_plans/task-delivery-contract.md`, the original unmet criterion mapping, and
|
|
149
|
+
all shipped integration work into exactly one successor named
|
|
150
|
+
`aport-task-delivery-workflow-integration`, only if still necessary. Check existing
|
|
151
|
+
jobs and PRs first. Use the target repository's instructions and configured base
|
|
152
|
+
(`staging` at observation time), not this repository's `main`.
|
|
153
|
+
|
|
154
|
+
From that authorized operator checkout, after reconciling controls and the pin:
|
|
155
|
+
|
|
156
|
+
```sh
|
|
157
|
+
gallivant status --json
|
|
158
|
+
gallivant ready docs/prds/aport-task-delivery-workflow-integration.md
|
|
159
|
+
gallivant start docs/prds/aport-task-delivery-workflow-integration.md --base staging --no-open
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
If the successor already exists, inspect and resume that identity using the normal
|
|
163
|
+
controls instead of starting another task. Human merge and qualified deployment
|
|
164
|
+
remain dependencies before host tests. The connected preview account exposes only
|
|
165
|
+
the onboarding qualification repository, so it cannot create this integration
|
|
166
|
+
job; repository operator controls and the actual M5 pin must be supplied there.
|
|
167
|
+
Do not reset the completed foundation, reopen its merged PR or weaken readiness.
|
|
168
|
+
|
|
169
|
+
## Upgrade and rollback
|
|
170
|
+
|
|
171
|
+
Use the installed `task-delivery-state` command and matching emitted manifests:
|
|
172
|
+
|
|
173
|
+
```sh
|
|
174
|
+
task-delivery-state check --home "$DURABLE_HOME" --manifest "$CURRENT_RUNTIME"
|
|
175
|
+
task-delivery-state backup --home "$DURABLE_HOME" --manifest "$CURRENT_RUNTIME" --out "$STATE_BACKUP"
|
|
176
|
+
task-delivery-state migrate --home "$DURABLE_HOME" --manifest "$NEXT_RUNTIME"
|
|
177
|
+
task-delivery-state rollback --backup "$STATE_BACKUP" --out "$RESTORED_HOME" --manifest "$CURRENT_RUNTIME"
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Coordinate maintenance with the existing owner lock; do not replace active pinned
|
|
181
|
+
jobs' artifact. Unsupported versions stop until a compatible migration exists.
|
|
182
|
+
Start the restored coordinator with its matching runtime and verify queued/active
|
|
183
|
+
identities and saved state without duplicate dispatch. Rebuild with the release
|
|
184
|
+
command above after code/configuration changes. Metadata/skills changes need a
|
|
185
|
+
new ZIP; eligible live MCP updates use **MCPs → connected server → Rescan** in the
|
|
186
|
+
existing portal draft. Preserve approved contracts and the registered MCP URL.
|
|
187
|
+
|
|
188
|
+
Current rules checked 2026-10-18: [submission](https://developers.openai.com/plugins/deploy/submission),
|
|
189
|
+
[extensions](https://developers.openai.com/plugins/build/extensions),
|
|
190
|
+
[remote MCP review](https://developers.openai.com/plugins/deploy/app-review).
|
|
191
|
+
The documented package metadata belongs under `extensions.com.openai`; reviewer
|
|
192
|
+
credentials and private instructions belong in the portal. Business identity,
|
|
193
|
+
org permissions, eligible publisher project residency, assigned domain challenge
|
|
194
|
+
and package/MCP/skill scans require actual outcomes. Publisher project eligibility
|
|
195
|
+
does not change APort customer residency. Never overwrite another plugin's domain
|
|
196
|
+
challenge. The owner alone performs remaining submission attestations/actions.
|