@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/learning.md
ADDED
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
# Learning from reviewed feedback
|
|
2
|
+
|
|
3
|
+
The repository-scoped learning service collects eligible feedback and keeps exact
|
|
4
|
+
candidate revisions for human review. A digest identifies content. Only an enrolled
|
|
5
|
+
Ed25519 OpenSSH signature can authorize an activation transition. Advice remains
|
|
6
|
+
advisory: it cannot change task scope, Verify commands, acceptance criteria, tools,
|
|
7
|
+
permissions, budgets, merge policy, reviewer eligibility or APort gates.
|
|
8
|
+
|
|
9
|
+
**Deployment status: UNQUALIFIED, collection only.** This implementation includes
|
|
10
|
+
the collector, review service, OpenSSH verifier, transition journal and shared input
|
|
11
|
+
seam. Installed coding adapters do not yet enforce an outer boundary protecting
|
|
12
|
+
learning authority from arbitrary worker code and privileged/control routes. No
|
|
13
|
+
configuration boolean, hash, file mode, approval flag or TTY enables application.
|
|
14
|
+
Setup, extraction and apply refuse that missing prerequisite. Fixture qualification
|
|
15
|
+
in tests is dependency injection, never a production enrollment mechanism.
|
|
16
|
+
|
|
17
|
+
The normative [architecture](https://github.com/uchibeke/gallivant/blob/main/docs/plans/review-feedback-learning.md) describes the full
|
|
18
|
+
delivery contract. Several implementation requirements remain outstanding; the
|
|
19
|
+
[qualification record](https://github.com/uchibeke/gallivant/blob/main/docs/audit/learning-qualification.md) distinguishes tested behavior
|
|
20
|
+
from those gaps. This release makes no effectiveness claim.
|
|
21
|
+
|
|
22
|
+
## Collection and review on Linux and macOS
|
|
23
|
+
|
|
24
|
+
Use Node 22+, the configured `gh` credential and the existing operator configuration
|
|
25
|
+
with `trusted_authors` and `reviewer`. Eligible prose is still untrusted data.
|
|
26
|
+
Repository identity is GitHub host plus immutable numeric repository ID; a fork or
|
|
27
|
+
replacement repository cannot inherit lessons by reusing an owner/name. This first
|
|
28
|
+
transport supports github.com; enterprise hosts are refused.
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
gallivant learn configure --repo owner/project --mode collect
|
|
32
|
+
gallivant learn --repo owner/project --since 2026-09-01 --until 2026-10-07 --dry-run
|
|
33
|
+
gallivant learn --repo owner/project --since 2026-09-01 --until 2026-10-07
|
|
34
|
+
gallivant learn list --repo owner/project --status pending
|
|
35
|
+
gallivant learn show lesson-validation --repo owner/project --revision SHA256
|
|
36
|
+
gallivant learn reject lesson-validation --repo owner/project --revision SHA256 --reason 'Contested correction'
|
|
37
|
+
gallivant learn report --repo owner/project
|
|
38
|
+
gallivant learn prune --repo owner/project
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Replace owner/project, IDs and digests with actual results. Dates are half-open UTC
|
|
42
|
+
dates. The default window is 30 days, with 100 PRs, 1,000 eligible findings, 60 API
|
|
43
|
+
pages and a 60-second collection deadline per invocation. PRs are scanned by update
|
|
44
|
+
time, including old PRs. Separate learning cursors never acknowledge coding events,
|
|
45
|
+
consume review rounds or change task identity. Automatic observation runs after
|
|
46
|
+
coding/review dispatch and does no extraction. A full source enumeration is needed
|
|
47
|
+
to flag deletion; filtered automatic reads cannot establish absence.
|
|
48
|
+
The automatic lane rotates a window of at most 100 due watched entries, independently
|
|
49
|
+
of request completion order. Idle progress ticks retain the next window.
|
|
50
|
+
|
|
51
|
+
Coverage, caps, continuation and rate-limit retry time are reported. Interrupted
|
|
52
|
+
scans resume the unfinished source kind and page within a PR. PR listing passes
|
|
53
|
+
retain their page cursor across invocations and skip persisted completed PR identities.
|
|
54
|
+
A pass that discovers new identities triggers another pass from page one to catch
|
|
55
|
+
PRs moved ahead of its cursor; completion requires a pass with no new identities.
|
|
56
|
+
Both passes respect the 60-page invocation budget and retain progress beyond page
|
|
57
|
+
60. The completed identity set remains capped at 10,000. Immutable evidence
|
|
58
|
+
revisions deduplicate overlap. Each page saves minimized findings and continuation
|
|
59
|
+
together, including pages containing only ineligible comments. Deletion is deferred
|
|
60
|
+
until the complete source has been enumerated. Required review context is minimized,
|
|
61
|
+
retained only through inline enumeration, and subject to the 30-day excerpt limit
|
|
62
|
+
from its stored observation timestamp, independently of a future scan endpoint.
|
|
63
|
+
Legacy buffers without a trustworthy observation timestamp are redacted on read or prune.
|
|
64
|
+
When `--until` is omitted, retries reuse the incomplete scan's original date window,
|
|
65
|
+
including after restart; completion allows the next invocation to open a fresh window.
|
|
66
|
+
Dry-run uses the same transport and eligibility rules but writes no learning state
|
|
67
|
+
and runs no inference. A source page reserves up to 200 eligible events (100 comments
|
|
68
|
+
and their review summaries), so an invocation can stop below the 1,000-finding cap.
|
|
69
|
+
Transport and parsing share a 64 MiB ceiling for each 100-item page before body
|
|
70
|
+
minimization. The 10,000-observation/context-identity storage bounds and continuously
|
|
71
|
+
moving upstream pagination can still leave coverage incomplete; inspect the report
|
|
72
|
+
before assuming full history was collected. No evidence link is opened or fetched.
|
|
73
|
+
Pruning uses the remembered immutable identity and removes expired local excerpts
|
|
74
|
+
even when GitHub is unavailable. Reconfiguration refuses a different resolved ID;
|
|
75
|
+
identity persistence also refuses replacement, preserving offline disable ownership.
|
|
76
|
+
Recovery uses the remembered immutable repository identity and signed local state,
|
|
77
|
+
so retrying revocation controls does not depend on GitHub availability. Verified
|
|
78
|
+
committed removals retry their controls even after qualification is lost; prepared
|
|
79
|
+
transitions still require qualification before activation. Batch
|
|
80
|
+
approval rejects multiple revisions of one candidate before preview or signing.
|
|
81
|
+
|
|
82
|
+
`reject` requires a nonempty `--reason` and applies only to pending or already
|
|
83
|
+
rejected revisions. `retire` also requires a reason and, when qualification is
|
|
84
|
+
available, targets an exact active revision through the signing workflow.
|
|
85
|
+
`approve` accepts an optional reason. These are distinct from changing a
|
|
86
|
+
repository's collection mode.
|
|
87
|
+
|
|
88
|
+
`revise` validates closed-schema JSON and creates an unapproved revision:
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
gallivant learn revise lesson-validation --repo owner/project --from reviewed-rule.json
|
|
92
|
+
gallivant learn show lesson-validation --repo owner/project --revision SHA256
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The review view contains exact text, applicability, literal project scopes, rationale,
|
|
96
|
+
example, evidence, fix disposition, overlap/repetition suggestions and digest. It is
|
|
97
|
+
escaped JSON, without a pager, executable Markdown or automatic URL opening. Editing
|
|
98
|
+
or combining evidence never inherits approval. Exact rejected revisions remain
|
|
99
|
+
suppressed. Contradictions require human judgment; repetition is a suggestion, not
|
|
100
|
+
validation. Copying guidance to AGENTS.md is optional ordinary reviewed navigation,
|
|
101
|
+
never enrollment or an automatic per-run rewrite.
|
|
102
|
+
|
|
103
|
+
Resolved source visibility is retained in evidence separately from immutable
|
|
104
|
+
repository identity; unavailable classification is reported as unknown. Dismissal
|
|
105
|
+
and deletion flags retain their first observed timestamp without changing evidence
|
|
106
|
+
hashes. Retracted evidence remains inspectable and is excluded from extraction.
|
|
107
|
+
Configuration persists the last-resolved visibility. Before storing automatic
|
|
108
|
+
observations, the post-dispatch collection step revalidates the immutable repository
|
|
109
|
+
ID and refreshes classification; a name replacement or lookup outage skips learning
|
|
110
|
+
without altering coding feedback. Identity checks share a five-second batch budget
|
|
111
|
+
and one lookup per repository per batch. Skips are logged and later ticks rotate
|
|
112
|
+
the bounded observation window. Legacy identity-only records remain readable.
|
|
113
|
+
Use historical collection to cover feedback missed while identity lookup was
|
|
114
|
+
unavailable; advancing coding cursors do not promise an automatic learning retry.
|
|
115
|
+
|
|
116
|
+
`learn configure --repo owner/project --mode off` uses the stored identity and invokes
|
|
117
|
+
local revocation controls even when GitHub, credentials or the remote repository are
|
|
118
|
+
unavailable. Enabling collection or application still resolves the remote identity.
|
|
119
|
+
Every configuration write advances a durable mode generation, including repeated
|
|
120
|
+
disables. An apply request awaiting qualification refuses to commit if that
|
|
121
|
+
generation changed; a new explicit apply request is required. Older state files
|
|
122
|
+
acquire this field on their next write without changing their current mode.
|
|
123
|
+
|
|
124
|
+
If revocation controls fail after the mode is saved, repeat the disabled-mode
|
|
125
|
+
command: both `off` and `collect` retry controls even when the mode is unchanged.
|
|
126
|
+
|
|
127
|
+
Extraction consumes stored evidence using the remembered immutable identity and
|
|
128
|
+
does not authenticate to GitHub or resolve the remote repository. With an
|
|
129
|
+
unqualified installed profile it reports unavailable even during a GitHub outage.
|
|
130
|
+
The service seam bounds a separate
|
|
131
|
+
allowance (maximum $1 per extraction), 30 seconds and 20 candidate revisions. It
|
|
132
|
+
persists an intent/reservation before invoking an injected data-only execution
|
|
133
|
+
dependency. Each intent reserves its exact observation revision digests; later
|
|
134
|
+
invocations select the next unreserved batch, including after restart. Unresolved
|
|
135
|
+
batches remain reserved and are not automatically repurchased. Legacy exact-batch
|
|
136
|
+
digests acquire revision keys when the same bounded input is encountered. No installed
|
|
137
|
+
production extractor currently implements that boundary; `dataOnly` metadata is not
|
|
138
|
+
an operator configuration option. List/show/report/explain cannot launch paid work.
|
|
139
|
+
|
|
140
|
+
Restricted task preparation now supplies shared native tool/context controls that
|
|
141
|
+
a future extraction adapter can reuse. It does not connect the learning extractor
|
|
142
|
+
or qualify ordinary coding workers, signing authority or control routes. The
|
|
143
|
+
[merged-boundary assessment](https://github.com/uchibeke/gallivant/blob/main/docs/audit/learning-qualification.md#merged-preparation-boundary-assessment)
|
|
144
|
+
records the reusable pieces, remaining integration work and external qualification
|
|
145
|
+
requirements. Preparation fixture results do not enable production learning.
|
|
146
|
+
|
|
147
|
+
## Approval workflow contract and prerequisites
|
|
148
|
+
|
|
149
|
+
These commands describe the intended workflow; **the deployment stages below refuse
|
|
150
|
+
today's unqualified profiles**. Do not run setup as a coding worker, install this
|
|
151
|
+
development branch as the coordinator or create production keys to test it.
|
|
152
|
+
|
|
153
|
+
OpenSSH must support both `ssh-keygen -Y sign` and `-Y verify`. `learn doctor` probes
|
|
154
|
+
these operations with a disposable key rather than relying on a version string.
|
|
155
|
+
Choose an absolute protected executable (default `/usr/bin/ssh-keygen`). The file
|
|
156
|
+
and every ancestor must be owned by root or the operator, with no group/other
|
|
157
|
+
write permission. Only the fixed system temporary root (`/tmp`, resolved through its system alias)
|
|
158
|
+
may be a root-owned sticky ancestor, and only above
|
|
159
|
+
a private trusted directory; the executable's immediate parent must never be
|
|
160
|
+
group/other-writable. These checks run on each pin, including after enrollment.
|
|
161
|
+
They do not isolate a worker running as the operator: that still requires the
|
|
162
|
+
qualified outer boundary. Linux
|
|
163
|
+
operators can install their distribution's `openssh-client`; macOS operators use
|
|
164
|
+
their system OpenSSH or an operator-installed portable build. Changes to the pinned
|
|
165
|
+
binary require requalification. The offline suite additionally uses Python 3 for
|
|
166
|
+
disposable PTY entry; it never asks for a human passphrase.
|
|
167
|
+
|
|
168
|
+
```sh
|
|
169
|
+
gallivant learn doctor --repo owner/project
|
|
170
|
+
gallivant learn setup --key-path /absolute/operator-approval/learning-ed25519 --ssh-keygen /usr/bin/ssh-keygen
|
|
171
|
+
gallivant learn approve lesson-validation --repo owner/project --revision SHA256
|
|
172
|
+
gallivant learn configure --repo owner/project --mode apply
|
|
173
|
+
gallivant learn explain --repo owner/project --run RUN_ID
|
|
174
|
+
gallivant learn retire lesson-validation --repo owner/project --revision SHA256 --reason 'Replaced by a regression test'
|
|
175
|
+
gallivant learn recover --repo owner/project
|
|
176
|
+
gallivant learn configure --repo owner/project --mode off
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
`GALLIVANT_HOME` can locate nonsecret state in another operator-owned home. The
|
|
180
|
+
private key has a separate explicit absolute path, supporting a separate account.
|
|
181
|
+
Both directories must be outside worker writes, without symlinks; approval directory
|
|
182
|
+
0700 and key 0600 are hygiene only. An enforced OS/container/account boundary must
|
|
183
|
+
also protect CLI/coordinator code, public trust, signer, active store and monotonic
|
|
184
|
+
checkpoint; deny private-key/credential/terminal access; and exclude privileged and
|
|
185
|
+
control routes that could escape it. Same-UID modes and APort hooks alone do not
|
|
186
|
+
qualify arbitrary shell execution. Current native escalation and hosted profiles
|
|
187
|
+
remain unsupported for production learning application.
|
|
188
|
+
|
|
189
|
+
When qualified, explicit interactive setup would ask OpenSSH to create a dedicated
|
|
190
|
+
Ed25519 key using bcrypt with at least 100 rounds, refuse existing files and
|
|
191
|
+
unencrypted keys, validate the public envelope and sign an enrollment manifest.
|
|
192
|
+
Choose a strong unique nonempty passphrase. Do not reuse GitHub signing/login keys
|
|
193
|
+
or load the key into an agent. Node never requests or stores the secret.
|
|
194
|
+
|
|
195
|
+
Approval freezes a complete preview, including every selected/removed revision and
|
|
196
|
+
evidence, then takes a separate explicit confirmation before fresh OpenSSH signing.
|
|
197
|
+
There is no `--yes`, wildcard, approve-all, alternate activation command or unsigned
|
|
198
|
+
flag. Signing uses a pinned executable and minimal environment: agent, askpass,
|
|
199
|
+
provider and dynamic-loader variables are absent; `SSH_ASKPASS_REQUIRE=never`.
|
|
200
|
+
An optional `--reason` on `learn approve` appears in the immutable preview and signed
|
|
201
|
+
transition as an audit explanation.
|
|
202
|
+
Cancellation or failed signing changes no active content. Signed prepared intent
|
|
203
|
+
may be recovered only against its exact current parent. The CLI currently selects
|
|
204
|
+
one revision per invocation; explicit batches are available only to the shared
|
|
205
|
+
service and enumerate every ID/digest in the preview.
|
|
206
|
+
`learn recover` also retries controls for committed retirements and replacements
|
|
207
|
+
from verified signed history, without signing or activating another transition.
|
|
208
|
+
Recovery verifies obsolete signed preparations whose sequence was already consumed
|
|
209
|
+
and moves them to a protected audit archive, then continues eligible preparations.
|
|
210
|
+
It never rebases an old signature. Invalid signatures still fail closed. The archive
|
|
211
|
+
retains exact signed bytes and disposition, is capped at 1,000 records, and its count
|
|
212
|
+
appears in `learn report`; older stores migrate the empty archive without read-time
|
|
213
|
+
writes. Include it in the same protected-store backup as approval history.
|
|
214
|
+
|
|
215
|
+
Activation checks canonical RFC 8785 bytes, SSHSIG namespace, enrolled signer,
|
|
216
|
+
repository identity, sequence/parent, evidence and complete active-set digests.
|
|
217
|
+
History, pointer and checkpoint commit through one fsynced atomic rename under the
|
|
218
|
+
existing process-identity lock. A stale signature requires another preview; rollback
|
|
219
|
+
is another signed transition. Hashes and timestamps alone authorize nothing.
|
|
220
|
+
|
|
221
|
+
Shared dispatch selects at most 20 lessons and 8 KiB, in stable ID order. Literal
|
|
222
|
+
project scopes match validated repository-relative paths from inline review events,
|
|
223
|
+
carried task files and the approved brief path. Up to 200 unique paths are selected
|
|
224
|
+
in stable order; invalid/absolute/traversing paths are excluded. The pinned paths
|
|
225
|
+
carry forward into resume, and unknown paths still omit project-scoped guidance.
|
|
226
|
+
It records bundle/rule,
|
|
227
|
+
original input, managed input and context digests plus omissions; actual delivery is
|
|
228
|
+
recorded after an accepted attempt ID exists. Pending and foreign material never
|
|
229
|
+
enters managed context. Retirement fences later delivery and uses existing
|
|
230
|
+
cancellation capabilities with honest confirmation limits. If old native memory
|
|
231
|
+
contains retired advice, ordinary resume refuses and preserves task, PR and code.
|
|
232
|
+
After the existing run settles, explicitly run `gallivant resume <handle> --fresh-session`. This saves a retryable transition and starts a new provider session
|
|
233
|
+
with the approved brief, current task/PR context and current approved advice. It
|
|
234
|
+
preserves checkout, branch, cursors, iteration, operation history and cumulative
|
|
235
|
+
allowance. Unconfirmed cancellation and unrelated stop fences remain blocking;
|
|
236
|
+
a provider returning the retired session is refused. Old memory is not erased.
|
|
237
|
+
When learning is `off` or `collect`, this fresh-session transition clears advice
|
|
238
|
+
locally without a learning-related GitHub lookup. Any independently required
|
|
239
|
+
provider or coding-workflow credentials still apply.
|
|
240
|
+
|
|
241
|
+
Prepared advice records the owning task before launch. Admission rechecks mode,
|
|
242
|
+
revocation and signed active revisions under the learning lock and holds that lock
|
|
243
|
+
through provider acceptance. Retirement or disable racing that launch reports a
|
|
244
|
+
busy operation and must be retried; it has not committed a stop. Once committed,
|
|
245
|
+
revocation also reaches accepted execution intents before registry publication.
|
|
246
|
+
Retired prepared inputs stay fenced across restart and re-enabling application.
|
|
247
|
+
The accepted-delivery outbox retries unconfirmed cancellation without redispatch.
|
|
248
|
+
|
|
249
|
+
Accepted run ownership, feedback cursors and pending delivery audit records are
|
|
250
|
+
saved together before writing to the learning store. If that store is locked or
|
|
251
|
+
unavailable, coding continues with its pinned context and the registry retains
|
|
252
|
+
the exact repository/input/run tuple. Coordinator ticks retry up to ten pending
|
|
253
|
+
records per entry, including after restart or completion. Lost replies are safe
|
|
254
|
+
to retry; an older audit cannot replace a later attempt's pinned context. A pending
|
|
255
|
+
audit warning means reports may temporarily omit that delivery, not that its worker
|
|
256
|
+
failed to start. Preserve the registry as well as the learning store during recovery.
|
|
257
|
+
|
|
258
|
+
A failed enrollment signature retains the newly created encrypted key and a protected
|
|
259
|
+
`enrollment-intent.json` containing only its identity, path and pinned signer metadata.
|
|
260
|
+
Setup prompts, key creation and signing run outside the global store lock. Each
|
|
261
|
+
write reacquires it and checks that the pending intent and authority are unchanged.
|
|
262
|
+
Retry `learn setup` with the same key path: it verifies the exact encrypted key and
|
|
263
|
+
signer, previews the pending enrollment and requests fresh signing. Cancellation
|
|
264
|
+
preserves the pending intent; substituted keys, paths or signers are refused. The
|
|
265
|
+
intent remains audit metadata after success and cannot replace an enrolled authority.
|
|
266
|
+
Include it in the protected-state backup; keep encrypted private keys separately.
|
|
267
|
+
|
|
268
|
+
## Privacy, backup and recovery
|
|
269
|
+
|
|
270
|
+
Raw excerpts are bounded to 2 KiB, redacted and escaped before persistence. Source
|
|
271
|
+
SHA-256 digests identify the full source without retaining it. Never copy complete
|
|
272
|
+
logs or secrets into candidates. Invalid controls, bidirectional text, paths,
|
|
273
|
+
schemas, duplicate JSON keys and encodings are refused. A configured application
|
|
274
|
+
cannot fall back to an unsigned or foreign bundle when trust/checkpoints fail.
|
|
275
|
+
|
|
276
|
+
Raw excerpt retention is 30 days; collection/observation mutations and `prune`
|
|
277
|
+
remove expired observation excerpts, and read-only inspection hides them immediately.
|
|
278
|
+
Minimized signed evidence, hashes, disposition and approval history are retained.
|
|
279
|
+
Deletion cannot remove copies in backups, GitHub or already delivered provider
|
|
280
|
+
memory. Review views disclose expired, superseded, deleted and incomplete evidence.
|
|
281
|
+
Back up encrypted keys separately from nonsecret state. A generic repository backup
|
|
282
|
+
must never bootstrap trust or move an approval checkpoint backward.
|
|
283
|
+
|
|
284
|
+
Rotation and lost/compromised-key recovery are not yet implemented as commands.
|
|
285
|
+
Disable application, preserve the journal and use explicit operator-reviewed
|
|
286
|
+
re-enrollment/continuity once supported. Do not replace authority.json or restore an
|
|
287
|
+
older checkpoint to simulate rotation. Local signatures cannot prove freshness after
|
|
288
|
+
arbitrary rollback of the entire protected installation; V1 has no remote witness.
|
|
289
|
+
|
|
290
|
+
Reports separate confirmed recurrence from evidence-count suggestions. Known cost
|
|
291
|
+
is traceable; unresolved usage is unknown, not zero. The delivered-run denominator
|
|
292
|
+
does not yet cover every eligible coding attempt, and review-round/latency outcome
|
|
293
|
+
correlation remains outstanding. Different task mixes cannot establish causal
|
|
294
|
+
effectiveness. Held-out deterministic cases and real disposable OpenSSH bypass tests
|
|
295
|
+
check regressions; separately authorized paired live trials would be required for
|
|
296
|
+
quantitative effectiveness claims.
|
|
297
|
+
|
|
298
|
+
## Qualification and troubleshooting
|
|
299
|
+
|
|
300
|
+
```sh
|
|
301
|
+
npm run test:learning
|
|
302
|
+
npm run test:learning:live -- --qualify
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
The first command makes no paid calls and enrolls no production authority. The
|
|
306
|
+
second is opt-in and probes disposable key/trust/verifier/checkpoint canaries plus
|
|
307
|
+
terminal and local-control access using OS isolation. When those probes pass, it
|
|
308
|
+
requires interactive creation/enrollment of a temporary encrypted key, exact approval,
|
|
309
|
+
context consumption by a process enclosed in that same profile, and signed retirement.
|
|
310
|
+
All keys/state are deleted afterward and no paid inference runs. Production stays
|
|
311
|
+
UNQUALIFIED even after that disposable ceremony: installed worker launch/control
|
|
312
|
+
integration is still outstanding. The recorded qualification audit does not supply
|
|
313
|
+
a successful production enrollment or live approval/delivery ceremony.
|
|
314
|
+
|
|
315
|
+
On macOS, `sandbox_apply: Operation not permitted` means the host cannot create the
|
|
316
|
+
required nested sandbox from that execution surface. Run the probe from an operator
|
|
317
|
+
terminal where sandbox-exec is permitted. On Linux, `/usr/bin/bwrap`, functioning
|
|
318
|
+
user/PID/network namespaces and a dedicated Node installation are prerequisites.
|
|
319
|
+
Neither fix alone enables production apply; the actual installed execution profile
|
|
320
|
+
still needs integration and qualification. Never weaken the boundary to turn a
|
|
321
|
+
test green. Normal unenrolled coding runs keep their existing behavior.
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
Delivery audit storage is limited to 1,000 exact operation records per repository
|
|
325
|
+
and 16 KiB per newly prepared record, including context, paths and omissions.
|
|
326
|
+
Reports disclose usage and limits. At capacity, new advice-bearing operations fail
|
|
327
|
+
before launch; existing retries, delivery acknowledgements, pruning, retirement,
|
|
328
|
+
and disabling remain available. Records are not silently evicted: prepared
|
|
329
|
+
revocation targets, exact retry identities, digests and accepted-run denominators
|
|
330
|
+
remain intact. Automatic archival is not implemented; do not delete audit records
|
|
331
|
+
or reset the store to bypass capacity. Disable application to continue without
|
|
332
|
+
advice while preserving the protected audit backup.
|
|
333
|
+
|
|
334
|
+
Approval confirmation and passphrase entry run without the shared store lock.
|
|
335
|
+
The service rechecks the complete frozen preview, mode, parent, sequence and trust
|
|
336
|
+
root after each interaction; concurrent changes require a new reviewed approval.
|
|
337
|
+
Extraction candidates may cite only evidence included in that reserved batch.
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
Extraction reserves exact observation revisions durably before releasing the store
|
|
341
|
+
lock for external execution. Other repositories and emergency disable can mutate
|
|
342
|
+
state during that wait. Results merge into newly loaded state only if the original
|
|
343
|
+
reservation is unchanged; disabled collection or stale evidence refuses candidate
|
|
344
|
+
insertion. A failed merge leaves the reservation intact and does not authorize
|
|
345
|
+
repeat inference. Known returned cost and token counts remain recorded even when
|
|
346
|
+
a concurrent change prevents accepting the proposals.
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
Delivery path audit details retain an encoded JSON sample of at most 2 KiB,
|
|
350
|
+
plus `pathAudit.digest`, `count` and `omitted` for the full accepted path list.
|
|
351
|
+
Rule selection still considers every accepted path, including those omitted from
|
|
352
|
+
the stored sample. Managed inputs retain the full list; the audit digest allows
|
|
353
|
+
that exact list to be checked without duplicating it in every delivery record.
|
|
354
|
+
|
|
355
|
+
The executable selected with setup's `--ssh-keygen` is pinned in protected
|
|
356
|
+
enrollment metadata and reused by later CLI and daemon services without another
|
|
357
|
+
flag. Pending enrollment retries also reuse that pin. Each cryptographic use,
|
|
358
|
+
including doctor probes, checks the exact executable path and digest before
|
|
359
|
+
execution; a changed or missing binary requires restoring the pinned installation
|
|
360
|
+
or separately reviewed requalification. Local collection and emergency disable
|
|
361
|
+
do not require resolving or executing the signer.
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
Omitted-rule audits retain at most 1 KiB of encoded detail, further reduced to
|
|
365
|
+
fit the delivery record's remaining byte budget. `omissionAudit` records the full
|
|
366
|
+
ordered list digest, total count, unsampled count and counts by omission reason.
|
|
367
|
+
Rule selection still traverses the entire verified active bundle; the sample does
|
|
368
|
+
not change relevance or context limits. Exact selected rule references and the
|
|
369
|
+
bundle digest remain available alongside this summary for audit reconstruction.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Network failures and recovery
|
|
2
|
+
|
|
3
|
+
`ENOTFOUND` means a hostname lookup failed. `EAI_AGAIN` indicates a temporary
|
|
4
|
+
resolver failure. Neither proves that a provider is down, credentials expired,
|
|
5
|
+
or APort denied a tool call. DNS can affect one hostname while other sites work.
|
|
6
|
+
|
|
7
|
+
## Automatic local recovery
|
|
8
|
+
|
|
9
|
+
For a recognized terminal connection error, Gallivant waits 1, 5, then 15 minutes
|
|
10
|
+
before up to three automatic resumes, on the next daemon tick after each deadline.
|
|
11
|
+
It preserves the session, checkout, pending work, review cursors and approved brief.
|
|
12
|
+
The normal resume preflight, permissions, dirty-work preservation and completion
|
|
13
|
+
gates still apply. A connection failure with no published progress does not count
|
|
14
|
+
as a completed review round. A run that pushed before failing is accounted for
|
|
15
|
+
normally and returns to review/CI monitoring; it cannot evade the round budget.
|
|
16
|
+
Retries may incur provider charges, subject to existing per-run and task allowances;
|
|
17
|
+
the retry budget is separate from `max_iterations`.
|
|
18
|
+
|
|
19
|
+
Counts and deadlines survive daemon restarts. The window begins when the terminal
|
|
20
|
+
failure is observed, before GitHub reconciliation; a simultaneous GitHub outage
|
|
21
|
+
cannot extend it. Published progress must still be reconciled before retrying.
|
|
22
|
+
No retry starts after the one-hour recovery window expires; an already-started
|
|
23
|
+
run retains its normal runtime limit.
|
|
24
|
+
The shared completion projection keeps pending retries monitored, so embedded
|
|
25
|
+
hosts continue waking the coordinator instead of treating the task as paused.
|
|
26
|
+
Exhaustion stops with `provider-network-exhausted` and notifies the operator.
|
|
27
|
+
Success or reconciled published progress resets the consecutive failure streak.
|
|
28
|
+
A manually authorized Resume starts a new streak after normal preflight.
|
|
29
|
+
|
|
30
|
+
Only short terminal errors containing `ENOTFOUND`, `EAI_AGAIN`, `ECONNRESET`,
|
|
31
|
+
`ECONNREFUSED` or `ETIMEDOUT` qualify. Missing results, unknown errors, authentication
|
|
32
|
+
failures, quota errors, policy denials, cancelled tasks and unknown process ownership
|
|
33
|
+
do not trigger automatic replay. A crash during launch stops for inspection rather
|
|
34
|
+
than guessing whether input was sent. Unrecognized error formats require manual
|
|
35
|
+
inspection. Hosted execution retains its transport reconciliation: this mechanism
|
|
36
|
+
never resubmits an ambiguously accepted remote operation.
|
|
37
|
+
|
|
38
|
+
Status, the dashboard and `gallivant why <handle>` show the error, retry count and
|
|
39
|
+
deadline. “Signed-in (API unchecked)” means the local version/login checks passed;
|
|
40
|
+
it does not prove inference access. OpenCode reports credential presence; Gemini
|
|
41
|
+
and Goose report only that the binary runs, with authentication unchecked.
|
|
42
|
+
**Recheck PR** refreshes review and CI; it cannot
|
|
43
|
+
clear a failed agent or pending network recovery. **Resume agent** continues the
|
|
44
|
+
session after you repair its prerequisites. Upgrades do not silently restart old
|
|
45
|
+
stopped jobs; resume those explicitly once.
|
|
46
|
+
|
|
47
|
+
Readiness checks use a bounded 20-second coordinator deadline by default; an
|
|
48
|
+
explicit `execution.deadlineMs` overrides it. A timeout or cancelled check leaves
|
|
49
|
+
dispatch blocked until a successful refresh, but does not prove credentials are
|
|
50
|
+
invalid. The remedy is to inspect host load/connectivity and retry the check,
|
|
51
|
+
rather than automatically logging in or reinstalling the CLI. Pending refreshes
|
|
52
|
+
are reported as pending checks.
|
|
53
|
+
|
|
54
|
+
## Portable diagnosis
|
|
55
|
+
|
|
56
|
+
Use the actual provider origin configured for your harness. For default Claude:
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
gallivant doctor --network https://api.anthropic.com
|
|
60
|
+
gallivant doctor --network https://api.anthropic.com --json
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
No config, login or daemon is required. This takes three bounded samples using
|
|
64
|
+
Node's OS DNS resolver and credential-free HTTPS, without `dig`, `curl`, `sudo`,
|
|
65
|
+
systemd, launchd or a desktop. It sends HEAD requests only to your supplied HTTPS
|
|
66
|
+
origin, follows no redirects, and rejects credentials, paths, queries and fragments.
|
|
67
|
+
HTTP 401/403/404 proves an HTTPS response was received, not model access. Exit 0
|
|
68
|
+
requires every sample to pass; exit 1 indicates a failure or invalid input.
|
|
69
|
+
Passing samples cannot rule out an intermittent failure.
|
|
70
|
+
|
|
71
|
+
HTTPS testing is direct, without proxy forwarding. Proxy environment presence is
|
|
72
|
+
reported without its values. If a proxy is mandatory, use your administrator's
|
|
73
|
+
approved proxy diagnostic too. This test does not qualify the harness's proxy route.
|
|
74
|
+
|
|
75
|
+
Capture results during a failure and compare on another approved network. If only
|
|
76
|
+
router DNS fails while direct queries to an approved resolver succeed, repair the
|
|
77
|
+
router or configure that resolver through your network administrator. If OS lookup
|
|
78
|
+
fails while direct DNS works, inspect the resolver, VPN and endpoint-filter logs.
|
|
79
|
+
Linux users can use `resolvectl status` where systemd-resolved is installed;
|
|
80
|
+
otherwise use the distribution's network manager. Do not blindly overwrite a
|
|
81
|
+
managed `/etc/resolv.conf`. On macOS use Network settings and filter logs.
|
|
82
|
+
Do not disable TLS validation, firewalls or sandboxing to hide the failure.
|
|
83
|
+
|
|
84
|
+
After repair:
|
|
85
|
+
|
|
86
|
+
```sh
|
|
87
|
+
gallivant why <handle>
|
|
88
|
+
gallivant resume <handle>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Platform and release qualification
|
|
92
|
+
|
|
93
|
+
Recovery uses Node 22+ and the existing runner, with no macOS-specific commands.
|
|
94
|
+
CI exercises Node 22/24 on Ubuntu Linux and macOS, including tarball installation.
|
|
95
|
+
That is not a guarantee for every Linux distribution, container or provider CLI.
|
|
96
|
+
Process inspection and the selected harness's runtime/sandbox remain prerequisites;
|
|
97
|
+
hosted-result verification needs the isolation tools in [installation](install.md).
|
|
98
|
+
Missing isolation fails closed. The coordinator must remain awake and running.
|
|
99
|
+
|
|
100
|
+
Require the full CI matrix and package smoke test before release, then qualify a
|
|
101
|
+
small live task in the intended environment. See [release readiness](releasing.md).
|