@weftlet/toolkit 0.1.2 → 0.2.1

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.
Files changed (55) hide show
  1. package/README.md +39 -3
  2. package/THIRD_PARTY_NOTICES.md +33 -0
  3. package/dist/application/hydrator.js +21 -6
  4. package/dist/application/overlay.js +46 -9
  5. package/dist/application/saved-evidence.d.ts +1 -0
  6. package/dist/configuration/config.d.ts +4 -0
  7. package/dist/configuration/config.js +12 -0
  8. package/dist/configuration/scip-project.d.ts +9 -0
  9. package/dist/configuration/scip-project.js +40 -0
  10. package/dist/extraction/codex-auth.js +9 -2
  11. package/dist/extraction/codex-command.d.ts +8 -0
  12. package/dist/extraction/codex-command.js +81 -0
  13. package/dist/extraction/document-references.d.ts +18 -0
  14. package/dist/extraction/document-references.js +94 -0
  15. package/dist/extraction/document.d.ts +9 -2
  16. package/dist/extraction/document.js +40 -47
  17. package/dist/extraction/module-request.d.ts +3 -0
  18. package/dist/extraction/module-request.js +25 -0
  19. package/dist/extraction/repository-nodes.d.ts +7 -0
  20. package/dist/extraction/repository-nodes.js +20 -0
  21. package/dist/extraction/routing.d.ts +14 -0
  22. package/dist/extraction/routing.js +151 -0
  23. package/dist/extraction/scip-project.d.ts +3 -0
  24. package/dist/extraction/scip-project.js +33 -0
  25. package/dist/extraction/semantic-process.js +17 -5
  26. package/dist/extraction/semantic.js +32 -5
  27. package/dist/extraction/static.d.ts +7 -3
  28. package/dist/extraction/static.js +15 -9
  29. package/dist/graph/query.js +21 -34
  30. package/dist/graph/ranking.d.ts +10 -0
  31. package/dist/graph/ranking.js +85 -0
  32. package/dist/interfaces/doctor.js +12 -3
  33. package/docs/ADR-002-saved-evidence.md +7 -1
  34. package/docs/ADR-003-draft-overlays.md +6 -0
  35. package/docs/ADR-004-rdf-query-path.md +6 -0
  36. package/docs/ADR-006-provider-boundaries.md +5 -0
  37. package/docs/ADR-010-committed-source-indexing.md +77 -0
  38. package/docs/ADR-011-explicit-document-links.md +48 -0
  39. package/docs/ADR-012-impact-ranking.md +50 -0
  40. package/docs/ADR-013-relative-module-requests.md +58 -0
  41. package/docs/ADR-014-routing-declarations.md +108 -0
  42. package/docs/ADR-015-repository-document-identity.md +57 -0
  43. package/docs/CONSUMER-TRIAL.md +166 -0
  44. package/docs/ENVIRONMENT-VALIDATION.md +9 -0
  45. package/docs/IMPACT-EVALUATION.md +363 -0
  46. package/docs/PROVIDERS.md +30 -2
  47. package/docs/RELEASE-1.0-PLAN.md +221 -0
  48. package/docs/RELEASING.md +16 -6
  49. package/docs/ROADMAP.md +53 -5
  50. package/docs/SOURCE-INVENTORY.md +10 -0
  51. package/docs/VALIDATION.md +438 -0
  52. package/docs/VIEWER.md +5 -0
  53. package/docs/WEFTLET-2.0-PLAN.md +282 -0
  54. package/docs/extraction-manifest.json +94 -17
  55. package/package.json +5 -2
@@ -0,0 +1,108 @@
1
+ # ADR 014: explicit routing declarations
2
+
3
+ Status: implemented as an opt-in source of candidate dependencies. No query ranking change.
4
+
5
+ The frozen dispatch evaluation has an archival consumer with no shared TypeScript symbol
6
+ or extracted route from its producer. Matching topic strings cannot establish a subscription,
7
+ particularly across environments, filters and consumer groups. A source change can therefore
8
+ have an operational consumer that static imports alone do not retrieve.
9
+
10
+ This increment accepts a small, explicit Weftlet mapping format. It does not parse a broker's
11
+ deployment configuration or verify a running subscription. The configuration selects exact
12
+ committed files through `routingSources`. The routing extractor performs no directory expansion,
13
+ glob lookup, network request or working-checkout read. Future deployment-format adapters
14
+ can supply stronger evidence separately without changing this declaration's meaning.
15
+
16
+ ## Configuration and source format
17
+
18
+ Add the optional field to `context-graph.config.json`:
19
+
20
+ ```json
21
+ { "routingSources": ["routing/events.json"] }
22
+ ```
23
+
24
+ Commit a source such as `routing/events.json`:
25
+
26
+ ```json
27
+ {
28
+ "schemaVersion": 1,
29
+ "routes": [
30
+ {
31
+ "id": "archive-completion",
32
+ "scope": "example/dispatch",
33
+ "channel": "dispatch.completed.v1",
34
+ "producer": "src/dispatch/executor.ts",
35
+ "consumer": "src/archive/consumer.ts"
36
+ }
37
+ ]
38
+ }
39
+ ```
40
+
41
+ Paths are exact, case-sensitive repository-relative names of regular committed files. No
42
+ suffix substitution, basename guessing, symbol resolution or endpoint behavior check occurs.
43
+ IDs, scopes and channel labels are literal, case-sensitive strings. Scope distinguishes the
44
+ context in which the mapping was written; it is not proof that an environment is deployed.
45
+ There are at most 16 source files, 64 KiB per file and 500 declarations in total. Unknown
46
+ fields and duplicate JSON keys are rejected. Filters, wildcards and consumer-group semantics
47
+ are unsupported; write only the explicit endpoint mapping this format can represent.
48
+
49
+ Run `weftlet config validate`, commit the source, then explicitly `weftlet hydrate --ref HEAD`.
50
+ Configuration validation checks source selection; hydration validates the selected committed
51
+ content. With `semanticSources: []`, this routing extraction makes no model requests.
52
+
53
+ ## Identity, citations and authority
54
+
55
+ Each `(repositoryId, scope, id)` identifies one binding Workflow node. The channel is an
56
+ attribute, not a shared join key. The producer `emits` that binding and the binding
57
+ `routesThrough` its consumer. Separate records do not imply every producer delivers to every
58
+ consumer with the same topic name. Shared endpoint files can still connect bindings because
59
+ an implementation change may affect more than one declared relationship.
60
+
61
+ Both facts cite the entire committed JSON source with path, line span, content digest and
62
+ commit SHA. Binding attributes identify the record. The citation proves what the mapping
63
+ declares; file existence does not prove that code publishes, subscribes or delivers an event.
64
+ `routing-declaration-extractor@1.0.0` emits `authority: inferred`,
65
+ `sourceAuthority: inferred`, and `extractionReview: deterministic`. Confidence 1 describes
66
+ faithful parsing of an explicit declaration, not delivery confidence. Even matching
67
+ `approvedIntentSources` does not promote these mappings into approved product intent.
68
+ No runtime observation or successful test result is synthesized.
69
+
70
+ The same facts flow through RDF/SPARQL, SHACL, impact queries and visualization. Facts do
71
+ not require a separate query projection or routing-specific ranking preference. A matching
72
+ file returned through these facts is a candidate dependency with declaration provenance.
73
+
74
+ ## Failure and editing behavior
75
+
76
+ Malformed, absent or non-regular configured source files fail committed refresh before model
77
+ extraction or indexing, preserving the last valid snapshot. Missing/non-regular endpoint
78
+ files suppress both relationships for that binding and produce a cited extraction-gap
79
+ diagnostic. Duplicate `(scope, id)` declarations across all selected files suppress every
80
+ record with that identity, including identical duplicates. No winner is chosen. These are
81
+ evidence gaps, not automatic architecture violations; diagnostics do not certify completeness.
82
+
83
+ Opted-in snapshots include the routing extractor version in their identity and manifest.
84
+ Snapshots without routing retain the existing graph-v4 identity construction. Saved queries
85
+ never refresh implicitly, and semantic artifact keys are unchanged.
86
+
87
+ Draft overlays capture the selected declarations and previously referenced endpoints alongside
88
+ normal source scope, then rebuild all routing relationships from the isolated draft. The
89
+ isolated archive preserves committed inputs even when `.gitignore` matches them. Deleted
90
+ declarations invalidate their bindings and produce a gap diagnostic. Renamed/deleted endpoints
91
+ invalidate a binding until its declaration names a present file. Draft facts and source authority
92
+ are labeled `draft`; citations retain the base SHA and the captured content digest. A new
93
+ endpoint outside captured source scope fails capture even if currently clean, so later edits
94
+ cannot evade freshness checks. Configure its source scope before rebuilding. Malformed draft sources preserve the previous
95
+ overlay head. Publication IDs bind the routing extractor version, and RDF/SHACL validation
96
+ runs before a routing overlay is published. Historical snapshots and committed heads remain
97
+ unchanged.
98
+
99
+ ## Validation boundary
100
+
101
+ Tests use real temporary Git repositories and actual TypeScript indexing. They cover exact
102
+ bindings, same-topic isolation, ambiguity, missing inputs, rename/delete, dirty saved querying,
103
+ artifact reuse, RDF/projection equivalence, draft authority and failed-refresh preservation.
104
+ An independent packed-consumer smoke checks the runtime asset and queries a declared consumer.
105
+ The frozen dispatch control remains intact; a separately committed declaration/configuration
106
+ is compared against a no-routing control at the same new input SHA. This tests extraction of
107
+ explicit source mappings and linkage to code, not discovery of undeclared routes or broker
108
+ delivery. Live semantic quality, browser interaction and provider authentication remain separate.
@@ -0,0 +1,57 @@
1
+ # ADR-015: Canonical repository document identities
2
+
3
+ Status: accepted for the document identity patch.
4
+
5
+ ## Problem
6
+
7
+ The 0.2.0 semantic prompt requested `component:file:<path>` for every repository path,
8
+ while deterministic Markdown linking used `document:<path>` for document files.
9
+ Independently valid model assertions could assign Component and Document to the same
10
+ file ID. Combining those facts correctly failed the single-kind SHACL constraint.
11
+ This is an extraction identity defect, not evidence of contradictory product intent.
12
+
13
+ ## Decision
14
+
15
+ Physical repository documents ending in `.md`, `.mdx` or `.txt` use
16
+ `document:<repository-relative-path>` with kind Document. The semantic hydration
17
+ boundary canonicalizes both reserved prefixes (`component:file:` and `document:`)
18
+ for those extensions, using the same file-node policy as deterministic document links.
19
+ This applies to Codex and module providers, before fact IDs, OML and artifact hashes
20
+ are computed. Diagnostic references are remapped with the assertions.
21
+
22
+ Paths retain their exact spelling and case; no basename matching, existence guess,
23
+ ownership inference or concept merging is performed. Distinct business concepts such
24
+ as `contract:retention` remain separate from the document that describes them.
25
+ Every assertion, predicate, citation, confidence and label is retained. Raw provider
26
+ output remains unchanged for inspection. Normalizing physical identity never approves
27
+ an assertion or establishes that a referenced file exists. Snapshot assembly continues
28
+ to mark semantic assertions inferred/unreviewed, independently of source approval.
29
+
30
+ The RDF identity and SHACL shape stay unchanged. Other conflicting kinds still fail
31
+ validation; this policy does not hide genuine conflicts or remove assertions.
32
+
33
+ ## Artifact and snapshot migration
34
+
35
+ An implementation-owned `repositoryNodeIdentityVersion: 1` participates in every
36
+ semantic artifact key, including custom providers with unchanged user configuration.
37
+ Codex's prompt contract advances to v3. Assembly advances to `graph-v5`, records the
38
+ policy version in the manifest and uses a different immutable snapshot ID even for
39
+ the same commit/configuration. Historical snapshots and artifacts remain untouched
40
+ and queryable; they are not relabeled as newly validated evidence.
41
+
42
+ The first semantic refresh after upgrading requires extraction under the new contract.
43
+ Unchanged subsequent refreshes reuse the new artifacts. Do not delete the old cache or
44
+ force a revision as an upgrade workaround. Provider cost for that first refresh remains
45
+ subject to the consumer's configured budgets and authorization.
46
+
47
+ ## Validation and limits
48
+
49
+ The public regression uses two committed documents referencing the same implementation
50
+ document, a deterministic module provider returning the conflicting legacy identities,
51
+ real TypeScript indexing, deterministic links and RDF/SHACL. It checks preserved facts,
52
+ citations and review authority, old-cache isolation and repeat reuse. An unnormalized
53
+ negative control retains the SHACL failure. This is provider-independent deterministic
54
+ coverage, not a claim that a private consumer's full extraction has passed.
55
+
56
+ Operational-config cache reuse, broad identity diagnostics and full-graph SHACL latency
57
+ remain separate work in the [1.0 plan](RELEASE-1.0-PLAN.md).
@@ -0,0 +1,166 @@
1
+ # Evaluate Weftlet in a real project
2
+
3
+ Run this trial on the machine where you develop the consumer project. Weftlet is a local
4
+ toolkit and MCP server; it does not require a hosted Weftlet service or this project's Codex
5
+ development workspace. Saved evidence queries work without a model login. Hydrating selected
6
+ prose uses the configured provider; an OAuth failure may block new extraction but does not
7
+ remove an already published snapshot.
8
+
9
+ Use a pinned, reviewed toolkit version and its matching documentation. npm `0.2.0` includes
10
+ explicit routing declarations, committed TypeScript source projects, document linkage and
11
+ the improved impact ranking. To evaluate a newer, unreleased commit, use both locally prepared
12
+ package archives from that same reviewed commit; see [release preparation](RELEASING.md).
13
+ Record the commit separately from the package version, which does not change with every
14
+ development commit.
15
+
16
+ ## Choose tasks before querying
17
+
18
+ Start with three small, real changes: a shared contract change, a downstream consumer across
19
+ an asynchronous boundary, and a local implementation change. Before the first query, write
20
+ down each task, changed paths, expected consumers/contracts/tests/documents and why they
21
+ matter. Include a few plausible but irrelevant files as noise controls. Record the expected
22
+ relationships, not just filenames. Keep these initial expectations when reviewing results;
23
+ record later corrections separately instead of changing the denominator after seeing a score.
24
+
25
+ Review configuration and source scope before hydration. Begin with a few explicitly selected
26
+ documents and bounded `maxDocuments`, `maxSourceBytes`, `timeoutMs` and `retries`. Keep your
27
+ existing ChatGPT login mode if that is your chosen provider; there is no need to switch to
28
+ API billing. See [provider configuration](PROVIDERS.md). A second unchanged hydration should
29
+ reuse semantic artifacts. Do not use `--force-semantic` for that check.
30
+
31
+ Commit the project inputs you want indexed. Hydration reads the chosen commit while leaving
32
+ the active checkout alone; it excludes uncommitted edits. Test/workspace source inclusion and
33
+ package aliases may need an explicit [TypeScript source project](ADR-010-committed-source-indexing.md).
34
+ Do not approve documents, add routing mappings or change extraction scope merely to improve
35
+ the first measurement. Record such changes as a separate comparison with its own snapshot.
36
+
37
+ ## Capture a private run
38
+
39
+ The following commands use Bash on Linux/WSL and an already installed project-local toolkit.
40
+ Ensure `.context-graph/` is ignored first. From the consumer repository root, start a dedicated
41
+ Bash session with `bash`, then run the blocks below in that same session. Fail-fast settings
42
+ exit that session on an error while retaining the bundle; fix the cause before starting a new
43
+ trial. Native PowerShell needs equivalent redirection/exit-status handling. This recipe does
44
+ not install packages, authenticate, commit files or upload results.
45
+
46
+ ```bash
47
+ set -euo pipefail
48
+ git check-ignore -q .context-graph/trials/
49
+ trial="$PWD/.context-graph/trials/$(date -u +%Y%m%dT%H%M%SZ)-$$"
50
+ mkdir -p "$trial"
51
+ printf 'Private trial directory: %s\n' "$trial"
52
+ weftlet_cmd=("$PWD/node_modules/.bin/weftlet")
53
+ config="$PWD/context-graph.config.json"
54
+
55
+ # Captures each command's exact arguments, streams, status and elapsed seconds.
56
+ capture() {
57
+ local label="$1" started=$SECONDS status
58
+ shift
59
+ test ! -e "$trial/$label.argv.json" || return 1
60
+ node -e 'process.stdout.write(JSON.stringify(process.argv.slice(1), null, 2)+"\n")' \
61
+ "$@" > "$trial/$label.argv.json"
62
+ date -u +%Y-%m-%dT%H:%M:%SZ > "$trial/$label.started.txt"
63
+ if "$@" > "$trial/$label.stdout" 2> "$trial/$label.stderr"; then
64
+ status=0
65
+ else
66
+ status=$?
67
+ fi
68
+ printf '{"exitCode":%s,"elapsedSeconds":%s}\n' "$status" "$((SECONDS-started))" \
69
+ > "$trial/$label.result.json"
70
+ return "$status"
71
+ }
72
+
73
+ capture project-commit git rev-parse HEAD
74
+ capture working-state git status --porcelain=v1 --untracked-files=all
75
+ capture runtime node -p 'JSON.stringify({node:process.version,platform:process.platform,arch:process.arch})'
76
+ capture packages npm ls @weftlet/toolkit @weftlet/core --json
77
+ capture config "${weftlet_cmd[@]}" config show --config "$config"
78
+ capture doctor "${weftlet_cmd[@]}" doctor --config "$config"
79
+ ```
80
+
81
+ Keep the initial task expectations in `expectations.md` in this private directory before
82
+ continuing. Retain your
83
+ package lockfile, toolkit commit if using a development build, and Codex version if selected.
84
+ `doctor` reports readiness without a model request; its successful exit does not mean every
85
+ reported dependency is available or that live extraction works. There is no CLI `--version`
86
+ command; the package metadata above records installed versions.
87
+
88
+ After reviewing source scope and the provider budget, run hydration and its reuse check:
89
+
90
+ ```bash
91
+ evidence_ref=$(cat "$trial/project-commit.stdout")
92
+ capture hydrate "${weftlet_cmd[@]}" hydrate --config "$config" --ref "$evidence_ref"
93
+ snapshot=$(node -e 'const fs=require("node:fs"); process.stdout.write(JSON.parse(fs.readFileSync(process.argv[1],"utf8")).snapshotId)' "$trial/hydrate.stdout")
94
+ capture hydrate-repeat "${weftlet_cmd[@]}" hydrate --config "$config" --ref "$evidence_ref"
95
+ capture diagnostics "${weftlet_cmd[@]}" diagnostics show --config "$config" --snapshot "$snapshot"
96
+ capture shacl "${weftlet_cmd[@]}" validate --config "$config" --snapshot "$snapshot"
97
+ ```
98
+
99
+ Compare `hydrate.stdout` and `hydrate-repeat.stdout`: with unchanged inputs/configuration,
100
+ expect the same `snapshotId` and `contentDigest`, zero `semanticExtracted` on the repeat and
101
+ the expected `semanticReused` count. With no selected prose, zero reused is expected and
102
+ does not test model extraction. A refresh failure is an infrastructure/extraction result,
103
+ not a semantic-quality pass. Keep its status and stderr, and query an earlier snapshot by
104
+ its recorded ID if useful; identify that historical evidence in the trial.
105
+
106
+ ## Record what the agent actually sees
107
+
108
+ Replace the example task and path with the first predeclared task. Keep this request fixed
109
+ while paginating, including its snapshot and budgets:
110
+
111
+ ```bash
112
+ request=(impact scan --config "$config" --snapshot "$snapshot" \
113
+ --changed-file src/example.ts --task 'Describe the planned change here' \
114
+ --max-facts 60 --max-depth 32 --json)
115
+ capture task1-page1 "${weftlet_cmd[@]}" "${request[@]}"
116
+ continuation=$(node -e 'const fs=require("node:fs"); process.stdout.write(JSON.parse(fs.readFileSync(process.argv[1],"utf8")).exploration?.continuation ?? "")' "$trial/task1-page1.stdout")
117
+ if test -n "$continuation"; then
118
+ capture task1-page2 "${weftlet_cmd[@]}" "${request[@]}" --continuation "$continuation"
119
+ fi
120
+ ```
121
+
122
+ For subsequent pages, read the token from the **last** response and keep a new filename for
123
+ each page. Start with a declared three-page budget per task; preserve the final continuation
124
+ and `depthLimitReached`/`truncated` fields if you stop there. Exhausting a page budget is not
125
+ proof that other consumers are absent. Repeat for tasks two and three with distinct labels.
126
+ Keep all pages actually used, including complete provenance, coverage, ranking version and
127
+ `evidenceState`. Queries do not refresh evidence. Historical or draft evidence cannot satisfy
128
+ current-diff validation just because it contains useful relationships.
129
+
130
+ For an agent using MCP, retain the actual `impact.scan` request arguments and complete tool
131
+ responses from the client session, including continuations and any errors. Weftlet does not
132
+ persist a tool-call transcript automatically. A separate CLI replay can aid diagnosis but
133
+ does not establish what the agent saw. Also retain a short account of what the agent changed
134
+ in its implementation or test plan because of these results, and the actual test outcomes.
135
+
136
+ Retain the selected immutable snapshot, not just the mutable head pointer. With workspace
137
+ storage, it is `<repositoryRoot>/<storagePath>/snapshots/<snapshotId>.json`; the default
138
+ `storagePath` is `.context-graph`. `storageScope: "user"` instead uses a configuration/checkout
139
+ hash directory under `~/.cache/context-graph`. Preserve the original store and exact
140
+ configuration if its resolved path is uncertain. Semantic artifacts under `artifacts/semantic/`
141
+ contain model output; keep them locally if extraction debugging is needed. They are not
142
+ required to query an existing snapshot. Do not copy credentials or whole account directories.
143
+
144
+ ## Review usefulness and share only the result
145
+
146
+ For each expected relationship, record whether it appeared on page one, later within budget,
147
+ or was missed. Distinguish an absent extracted link from a reachable link beyond the budget
148
+ when the retained snapshot permits that diagnosis. Manually check cited source lines against
149
+ the recorded commit and assess whether the relationship is supported. Record wrong identities,
150
+ contradictions, misleading authority, irrelevant results and useful unexpected discoveries.
151
+ Intent approval, model assertion review, implementation, tests and runtime observations remain
152
+ separate; a test-file link does not prove that a test ran or passed.
153
+
154
+ Record elapsed hydration/query time, cache reuse, provider failures and whether the findings
155
+ changed the development decision. Keep missing evidence, rule violations and infrastructure
156
+ failures separate. These three tasks are a bounded usefulness trial, not a universal accuracy
157
+ score or a merge gate. Optional [source-checkout evaluation tooling](IMPACT-EVALUATION.md)
158
+ can score saved snapshots using an independently authored case suite; it is not an installed
159
+ `weftlet evaluate` command, and its reduced witnesses do not replace the raw pages above.
160
+
161
+ Keep the bundle private with the consumer project: configuration, paths, task text, snapshots,
162
+ model artifacts and agent transcripts can contain private product information. Do not dump
163
+ environment variables, login files or full prompts into a shared report. Share a reviewed
164
+ summary containing versions/SHAs, counts, timings, misses and a small sanitized reproduction
165
+ when possible. Browser checks can be done separately using the [viewer guide](VIEWER.md)
166
+ and [interaction checklist](ENVIRONMENT-VALIDATION.md#browser-run-through-browser-mcp).
@@ -3,6 +3,10 @@
3
3
  macOS is outside the maintainer's current validation scope. Treat the following checks
4
4
  separately; a live model provider is not a prerequisite for deterministic development.
5
5
 
6
+ These cloud checks concern the Codex workspace used to develop Weftlet. Consumer repositories
7
+ run the installed toolkit locally; they do not need this workspace or a hosted Weftlet service.
8
+ Use the [consumer trial](CONSUMER-TRIAL.md) to evaluate actual project usage.
9
+
6
10
  ## Hosted CI: verified
7
11
 
8
12
  GitHub-hosted Ubuntu run [39492039168](https://github.com/jchewitt/weftlet/actions/runs/39492039168)
@@ -17,6 +21,11 @@ passed at `4cdc4e5bc8b53bde3b23ce0be550146ac6ae817c`: the full Ubuntu job and a
17
21
  Windows job covering storage contention, committed archive bytes and all original MCP startup
18
22
  cases. This Windows subset does not establish full Windows release-preparation readiness.
19
23
 
24
+ The Windows reliability increment passed [run 39676848049](https://github.com/jchewitt/weftlet/actions/runs/39676848049):
25
+ 34 native Windows tests plus repository inventory and license checks, and the full Ubuntu
26
+ publication gate with 178 deterministic tests. The npm launchers use a synthetic CLI fixture;
27
+ this does not claim live Codex authentication or a full Windows publication gate.
28
+
20
29
  ## Fresh cloud: requires a new task
21
30
 
22
31
  Before publishing the current environment snapshot: