mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-19 14:32:59 +08:00
docs: record Cloudflare HTTPS and provider persistence acceptance [skip ci]
This commit is contained in:
+3
-1
@@ -17,6 +17,8 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
### Extension preview
|
||||
|
||||
- Add a deployed Cloudflare marketplace preview with dedicated D1/private R2, reviewed OAuth operator import/backup/restore, expiring publication windows and actual HTTPS graph acceptance. Provider redeployment and detached restore preserve immutable releases; public publishing is disabled after controlled validation.
|
||||
|
||||
- Reconcile global semantic-extension links after sync or explicit file indexing with an atomic candidate rebuild. Failed passes preserve the working graph. Reuse bounded core parse results on warm project instances while rerunning all framework hooks, global resolution and semantic passes; cold or disabled reuse retains full parsing. Reject observed source changes before commit and reclaim interrupted graph-only candidates. Rebuild text search and built-in secondary indexes in bulk inside the atomic replacement transaction.
|
||||
|
||||
- Prepare immutable Drupal extension 0.1.1: ignore unrelated static receivers and commented/quoted declarations, and resolve both explicit Symfony event argument orders. Preserve the reviewed 0.1.0 artifact and policy.
|
||||
@@ -24,7 +26,7 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
- Add project-scoped framework and semantic extensions, managed package installation, worker loading, and graph refresh on install/update/enable/disable/remove. Failed activation preserves the previous project configuration and graph.
|
||||
- Add an external Drupal extension for declared routes/forms, services, hooks, plugins and event subscribers. Literal route paths can be explore endpoints; extension edges retain their labels and registration sites. Comments and quoted examples do not count as PHP invocations.
|
||||
- Add a local marketplace preview with signed publisher submissions, immutable releases, publisher ownership checks and a companion connection for project selection. Mobile detail pages retain version, compatibility and source information. Hosted deployment remains follow-up work; this is not a release announcement.
|
||||
- Add a local marketplace preview with signed publisher submissions, immutable releases, publisher ownership checks and a companion connection for project selection. Mobile detail pages retain version, compatibility and source information. The dedicated Cloudflare preview now has separate hosted acceptance evidence; this is not a release announcement.
|
||||
- Extension authors can generate a starter with `codegraph extensions create`, test real graph contributions and removal with `codegraph extensions test`, and use the public SDK types and author guide without private core imports.
|
||||
|
||||
- Marketplace and headless registry installs now select the highest stable semantic version compatible with the connected engine and extension API. Automatic updates refuse downgrades; explicit pins (including prereleases) never substitute another version. Downloaded identity, compatibility and integrity are rechecked locally.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Cloudflare marketplace preview
|
||||
|
||||
Cloudflare is the preferred hosted target. The existing Node/SQLite service remains a portable reference implementation; it is not the Worker runtime. No Cloudflare account, resources, hostname, deployment or plan has been verified by this increment. `marketplace.getcodegraph.com` is proposed, not configured. Do not provision a Vercel marketplace for this delivery.
|
||||
Cloudflare is the preferred hosted target. The existing Node/SQLite service remains a portable reference implementation; it is not the Worker runtime. A dedicated Workers/D1/private-R2 preview is deployed at https://codegraph-marketplace-preview.colby-7d9.workers.dev on the account’s existing Workers Paid plan. R2 Standard activation was separately approved; no plan upgrade was made. See the [dated hosted acceptance report](../validation/extensions-cloudflare-hosted-20260922.md) for exact deployed versions, resource inventory, proof and remaining limits. `marketplace.getcodegraph.com` is proposed, not configured. Do not provision a Vercel marketplace for this delivery.
|
||||
|
||||
## Architecture and publication contract
|
||||
|
||||
@@ -29,7 +29,7 @@ CLOUDFLARE_REGISTRY=1 PLAYWRIGHT_MODULE=/absolute/path/to/playwright \
|
||||
node scripts/validation/marketplace-browser.cjs
|
||||
```
|
||||
|
||||
The exact Wrangler/Miniflare/workerd versions are pinned in the separate lockfile. Current Wrangler uses Miniflare 5 alpha; the local adapter uses its documented v4-options converter and explicit `resourcePersistencePath`. Default test state is disposable. Production configuration points to `worker.ts`; only `test-worker.ts` accepts failure/kill controls. Tests exercise real local D1/R2 bindings, Web Crypto, HTTP and test-owned subprocess kills, not JavaScript storage mocks. Static assets in integration tests are delivered through a local binding; Wrangler dry run validates bundling and asset/binding configuration; actual platform routing still needs hosted verification.
|
||||
The exact Wrangler/Miniflare/workerd versions are pinned in the separate lockfile. Current Wrangler uses Miniflare 5 alpha; the local adapter uses its documented v4-options converter and explicit `resourcePersistencePath`. Default test state is disposable. Production configuration points to `worker.ts`; only `test-worker.ts` accepts failure/kill controls. Tests exercise real local D1/R2 bindings, Web Crypto, HTTP and test-owned subprocess kills, not JavaScript storage mocks. Static assets in integration tests are delivered through a local binding; Wrangler dry run validates bundling and asset/binding configuration; actual platform routing is covered separately by the hosted acceptance.
|
||||
|
||||
For a retained local rehearsal (no Cloudflare account needed):
|
||||
|
||||
@@ -48,26 +48,50 @@ Required capabilities: authenticated Cloudflare account inventory, permission to
|
||||
|
||||
1. Inspect account/plan, D1/R2 inventory, existing Workers and `getcodegraph.com` zone ownership. Confirm included allowances and whether R2 activation requires billing. No paid upgrade, card entry, R2 activation, DNS or domain change is authorized by this guide.
|
||||
2. Copy `wrangler.jsonc` to a private deployment config beside it. Replace the placeholder D1 ID and bucket name with the verified preview resources and set the verified account ID. Keep `PUBLISHING_ENABLED=false` until storage, budget and runtime checks complete. Keep the initial `workers.dev` preview; attach a custom domain only with authorization. Do not run a deploy against the checked-in placeholder config.
|
||||
3. Apply `migrations/0001_registry.sql` to the dedicated empty preview D1 using `wrangler d1 migrations apply DB --remote --config wrangler.deploy.json`. Existing registry data must never be reset. No migration/provision/deploy has been run remotely by this increment.
|
||||
4. Check `wrangler deploy --dry-run --config wrangler.deploy.json --experimental-provision=false --experimental-auto-create=false`, then deploy the reviewed preview using the same flags without `--dry-run` only once resource access/authorization are verified. Automatic resource creation is disabled. The build bundles semver and shared validation; D1/R2 storage outlives Worker code replacement.
|
||||
3. Apply `migrations/0001_registry.sql` to the dedicated empty preview D1 using `wrangler d1 migrations apply DB --remote --config wrangler.deploy.json`. Existing registry data must never be reset. Both migrations have now been applied to the isolated preview. The combined Wrangler migration endpoint returned `SQLITE_ERROR: incomplete input`; the supported OAuth operator below applied the same unmodified statements transactionally with a migration ledger. Do not reset data after a migration error: inspect the actual schema first.
|
||||
4. Check `wrangler deploy --dry-run --config wrangler.deploy.json`, then deploy that exact config without `--dry-run` only once resource access/authorization are verified. Explicit real resource IDs/names are required for every storage binding; do not accept automatic provisioning prompts. The build bundles semver and shared validation; D1/R2 storage outlives Worker code replacement.
|
||||
5. Verify `/api/health`, exact deployed source, asset CSP and private bucket access. Enable publication only after measuring actual deployed CPU/memory and confirming usage controls. Publish disposable preview versions, replace the Worker code while keeping bindings, and verify unchanged identity, ownership and byte-identical downloads. Repeat browser signed publication, compatible one-Install into a separate Python project, actual graph refresh, update/disable/remove and origin/window/outage checks over the stable HTTPS origin.
|
||||
|
||||
The community publish API assigns `official=false` and rejects explicit official/publisher-identity spoof fields. The [trusted Drupal operator](official-drupal-import.md) now supplies a reviewed pinned-artifact plan/apply command, with exact registry identity, immutable publication and safe repeat operations. Apply migration `0002_official_operator.sql` after `0001_registry.sql` before using that command. There is no unauthenticated official/admin endpoint. Actual remote operator execution remains unverified; the local Node service's optional official seed is unchanged.
|
||||
The community publish API assigns `official=false` and rejects explicit official/publisher-identity spoof fields. The [trusted Drupal operator](official-drupal-import.md) now supplies a reviewed pinned-artifact plan/apply command, with exact registry identity, immutable publication and safe repeat operations. Apply migration `0002_official_operator.sql` after `0001_registry.sql` before using that command. There is no unauthenticated official/admin endpoint. The supported OAuth binding operator was exercised against the dedicated provider resources; the local Node service's optional official seed is unchanged.
|
||||
|
||||
## Remote backups and isolated restore
|
||||
## Supported OAuth operator and provider snapshots
|
||||
|
||||
A D1 Time Travel restore alone does not restore R2. Keep immutable objects and no expiration rules, and create an independent archive containing **both** metadata and all referenced objects. The binding-level format/tool is a local rehearsal; remote operator steps require authenticated Wrangler and are not claimed tested against a Cloudflare account:
|
||||
`hosted-ops.mjs` uses supported Wrangler `getPlatformProxy({remoteBindings:true})`. D1/R2 operations run against the explicitly configured provider resources, while the operator process runs locally. It never reads or copies OAuth credentials, and adds no public admin endpoint. It verifies an exact config digest, account/resource identities, publishing-disabled state and live deployed bindings before normal operations. Use `remote:true` on both bindings, no routes, and dedicated preview names. The private config must be JSON, beside `wrangler.jsonc` so relative paths remain correct.
|
||||
|
||||
1. Export a consistent D1 SQL snapshot: `wrangler d1 export DB --remote --config wrangler.deploy.json --output /absolute/new-backup/registry.sql`.
|
||||
2. Export the release object-key/hash/size inventory from that snapshot. With writes stopped, a D1 `SELECT object_key,integrity,size FROM releases` through `wrangler d1 execute DB --remote --json --command ...` also matches it. Do not combine unrelated snapshots. Fetch each private object using `wrangler r2 object get BUCKET/KEY --remote --file /absolute/new-backup/objects/HASH --config wrangler.deploy.json`. Verify SHA-256/size/package identity for every row, then write the archive manifest last. Copy the completed archive and a trusted checksum to an independent destination; define retention and recovery objectives.
|
||||
3. Restore exclusively into a **new, detached, empty** D1/R2 pair with no serving Worker or writers. Verify the archive before writes; upload each verified object first with `wrangler r2 object put ... --remote --file ...`, then import the metadata SQL with `wrangler d1 execute DB --remote --file ...`. Never run restore SQL on the live database. Keep the pair detached if any import is incomplete.
|
||||
4. Bind a separate read-only preview Worker to the restored pair and verify every listed artifact, identity and owner before cutover. Do not attach the original public domain until the operator approves a cutover. Provider backup, restore, retention and redeploy acceptance remain open until these commands actually run on verified resources.
|
||||
From repository root, after normal supported Wrangler authentication and authorized resource inspection:
|
||||
|
||||
```sh
|
||||
export CLOUDFLARE_ACCOUNT_ID=VERIFIED_ACCOUNT_ID
|
||||
export WRANGLER_LOG_PATH="$PWD/.qa/hosted/wrangler"
|
||||
export WRANGLER_REGISTRY_PATH="$PWD/.qa/hosted/dev-registry"
|
||||
export MINIFLARE_REGISTRY_PATH="$WRANGLER_REGISTRY_PATH"
|
||||
sha256sum marketplace/cloudflare/wrangler.deploy.json
|
||||
node marketplace/cloudflare/hosted-ops.mjs inspect marketplace/cloudflare/wrangler.deploy.json REVIEWED_CONFIG_SHA
|
||||
node marketplace/cloudflare/hosted-ops.mjs migrate marketplace/cloudflare/wrangler.deploy.json REVIEWED_CONFIG_SHA
|
||||
node marketplace/cloudflare/hosted-ops.mjs apply marketplace/cloudflare/wrangler.deploy.json REVIEWED_CONFIG_SHA /absolute/plan.json REVIEWED_PLAN_SHA
|
||||
node marketplace/cloudflare/hosted-ops.mjs backup marketplace/cloudflare/wrangler.deploy.json REVIEWED_CONFIG_SHA /absolute/new-snapshot
|
||||
```
|
||||
|
||||
Keep publication disabled and deployment/migration/import writers stopped for backup. One D1 batch captures identity, ownership, releases and recent nonces; every referenced immutable R2 object is copied and verified. `complete.json` is written last and pins `snapshot.json`; each release pins its package hash/size/identity. Rate counters are ephemeral and intentionally omitted. Unreferenced failed-upload objects are not part of a registry snapshot. An occupied snapshot path is refused. D1 Time Travel alone is not an R2 backup.
|
||||
|
||||
Create a **new authorized detached** D1/R2 pair and config named `codegraph-marketplace-preview-restore-...`; verify no Worker deployment exists under that name. Then:
|
||||
|
||||
```sh
|
||||
node marketplace/cloudflare/hosted-ops.mjs migrate marketplace/cloudflare/wrangler.restore.json REVIEWED_RESTORE_CONFIG_SHA --detached
|
||||
node marketplace/cloudflare/hosted-ops.mjs restore marketplace/cloudflare/wrangler.restore.json REVIEWED_RESTORE_CONFIG_SHA /absolute/completed-snapshot --detached
|
||||
```
|
||||
|
||||
Restore validates all bytes and metadata before upload, refuses occupied D1/R2, writes objects first and then commits metadata in one D1 batch. A failed partial restore stays detached; retry into a new destination, never reset live storage. Only after success deploy a separate read-only Worker bound to the restored pair and verify all releases plus identity/ownership against the snapshot. No original hostname cutover is implied. Preserve source/version/config and snapshot checksums separately from the backup bytes.
|
||||
|
||||
For a controlled publication test, add `PUBLISHING_ENABLED="true"` and `PUBLISHING_UNTIL="ABSOLUTE_UTC_ISO_DEADLINE"` to a reviewed temporary config. Health and POST both fail closed at expiry or for an invalid deadline. Hosted tests must always set the deadline; omission retains the existing local fixture behavior. Redeploy the original `false` config immediately after acceptance, verify health and a rejected POST, then take the backup. The deadline is a publication control, not a spending cap or a global writer lock.
|
||||
|
||||
Retain the provider restore pair and completed snapshot for review; no automatic deletion, scheduled backup or cutover is installed. Proposed operator retention: seven daily and four weekly complete snapshots, with a checksum verified at an independent approved destination. This proposal has not been scheduled, and the workspace snapshot is not evidence of off-site disaster recovery. Define RPO/RTO and approve cleanup separately.
|
||||
|
||||
## Costs and limits: planning assumptions, not a bill estimate
|
||||
|
||||
Sources checked September 22, 2026: [Workers pricing](https://developers.cloudflare.com/workers/platform/pricing/), [Workers limits](https://developers.cloudflare.com/workers/platform/limits/), [D1 pricing](https://developers.cloudflare.com/d1/platform/pricing/), [D1 limits](https://developers.cloudflare.com/d1/platform/limits/), [R2 pricing](https://developers.cloudflare.com/r2/pricing/). Account-wide usage by other applications must be included.
|
||||
|
||||
Workers Free allows 100,000 dynamic requests/day and 10 ms CPU per invocation; static asset requests bypassing the Worker are free. Memory is 128 MB per isolate. Workers Paid starts at $5/month and includes 10 million requests and 30 million CPU-ms/month, with request/CPU overages. It is not an all-in marketplace price. No paid plan has been selected or activated.
|
||||
Workers Free allows 100,000 dynamic requests/day and 10 ms CPU per invocation; static asset requests bypassing the Worker are free. Memory is 128 MB per isolate. Workers Paid starts at $5/month and includes 10 million requests and 30 million CPU-ms/month, with request/CPU overages. It is not an all-in marketplace price. The actual account already had Workers Paid active. This milestone did not select or upgrade that plan.
|
||||
|
||||
D1 Free includes 5 million rows read/day, 100,000 rows written/day and 5 GB total storage (500 MB per database). R2 Standard includes 10 GB-month, 1 million Class A and 10 million Class B operations/month. Beyond included R2 usage, Standard storage is $0.015/GB-month, Class A $4.50/million and Class B $0.36/million; egress is free. Backups, orphan objects, repeated checks and abuse consume storage/operations too. Free allowances do not authorize billable activation or guarantee a zero bill.
|
||||
|
||||
@@ -75,4 +99,20 @@ Illustrative small preview, **not measured demand**: 100 extensions × 3 release
|
||||
|
||||
The 8 MiB package contract has a 12 MiB signed JSON/base64 envelope. Package/signature verification and hashing may exceed the Free 10 ms CPU budget, and concurrent large requests may pressure 128 MB memory. Local wall time includes I/O and is **not Cloudflare CPU billing evidence**. Measure representative and maximum-size deployed requests before choosing a plan; if Free cannot support the contract, return the measured limit and a priced option for approval rather than silently lowering the size limit or enabling a paid plan. D1 stores only bounded metadata, avoiding its 2 MB row limit. The 1,000-release preview cap requires a catalog-pagination redesign before larger scale.
|
||||
|
||||
No hosted HTTPS, provider persistence, custom domain, cost ceiling, power-loss, multi-region behavior or production readiness is claimed by local runtime tests. Broader Drupal coverage/performance review remains separate; historical measured rebuild overhead is 22–30% with limited samples.
|
||||
Local runtime tests alone do not establish hosted behavior. The dated hosted report records actual HTTPS and provider persistence separately. Custom domain, hard cost ceiling, provider power-loss, multi-region behavior and production readiness remain outside that proof. Broader Drupal coverage/performance review remains separate; historical measured rebuild overhead is 22–30% with limited samples.
|
||||
|
||||
## Current preview and measured limits
|
||||
|
||||
The main preview and separate restored preview both have publication disabled. They retain official Drupal 0.1.1 plus clearly labeled acceptance fixtures (including deliberately incompatible/broken versions); do not recommend those fixtures for real projects. No cleanup, DNS cutover or custom-domain attachment was performed.
|
||||
|
||||
Use this branch’s built CLI to connect an explicitly selected local project, keeping the process running:
|
||||
|
||||
```sh
|
||||
node dist/bin/codegraph.js extensions connect /absolute/project --marketplace https://codegraph-marketplace-preview.colby-7d9.workers.dev
|
||||
```
|
||||
|
||||
Open the printed connection link, allow the local companion once, select the destination and review the publisher before Install. The browser never receives a filesystem API. Stopping the companion disconnects it. The published npm release is not claimed to include this draft branch.
|
||||
|
||||
Actual Paid-plan CPU measured on one accepted 8 MiB signed publication was **379 ms**; three full downloads measured **22, 26 and 20 ms**. These samples exceed the Free 10 ms budget: do not target Free for the full current contract. The configured preview cap is 1,000 CPU-ms/request; no plan upgrade was made. The 262-event final trace recorded no execution exceptions or `exceededMemory` outcomes, but exposes no heap high-water mark. Peak memory and concurrent large-request headroom remain unmeasured; 128 MB is a per-isolate platform limit, not measured consumption. These modest tests are not a load or cost guarantee.
|
||||
|
||||
Provider D1 readback reported 94,208 bytes for each dedicated database. Actual R2 binding lists found 17 objects / 8,742,210 bytes per bucket, with no orphans. CLI bucket analytics still reported zero objects/bytes at readback, so those delayed counters were not used as storage proof. Account-wide Workers/D1/R2 usage and billing remain independent of these fixture counts. Logs, backups and repeated verification also consume allowances.
|
||||
|
||||
@@ -51,11 +51,11 @@ node ops.mjs serve /absolute/preview-registry
|
||||
|
||||
A second apply returns `unchanged` only if all immutable metadata and actual object bytes still agree. `inspect-local` refuses an absent/uninitialized registry; it never provisions remote resources. For an existing local rehearsal made before migration 0002, start/stop the updated `ops.mjs serve` once before import. This helper automatically migrates only its explicit local state.
|
||||
|
||||
## Remote preparation and execution — not yet exercised against an account
|
||||
## Remote preparation and execution
|
||||
|
||||
No remote import has been performed. Klaus owns account access. A browser login does not establish API credentials or permission to activate resources. Do not deploy/create resources, edit DNS, enable billing or run these remote writes until the actual account, included resources, permissions and approved target have been verified.
|
||||
Official Drupal 0.1.1 has been imported into the dedicated preview using the supported Wrangler OAuth binding operator. The legacy direct HTTP/S3 adapter below still has only mocked contract evidence. Klaus owns account coordination; a browser login alone does not establish CLI authentication or resource authority. Do not deploy/create resources, edit DNS, enable billing or run these remote writes until the actual account, included resources, permissions and approved target have been verified.
|
||||
|
||||
1. Verify the preview Worker, private R2 Standard bucket and D1 database belong to the intended account. Apply **both migrations** to the authorized preview using `wrangler d1 migrations apply DB --remote --config wrangler.deploy.json`. Back up existing data first; do not reset the database. Obtain the actual registry ID with `wrangler d1 execute DB --remote --config wrangler.deploy.json --command "SELECT value FROM registry_meta WHERE key='id'"`. No such command was executed remotely during local acceptance.
|
||||
1. Verify the preview Worker, private R2 Standard bucket and D1 database belong to the intended account. Apply **both migrations** to the authorized preview using `wrangler d1 migrations apply DB --remote --config wrangler.deploy.json`. Back up existing data first; do not reset the database. Obtain the actual registry ID with `wrangler d1 execute DB --remote --config wrangler.deploy.json --command "SELECT value FROM registry_meta WHERE key='id'"`. The current actual provider proof is recorded separately from the earlier local acceptance.
|
||||
2. Create a private target JSON containing only public resource identifiers:
|
||||
|
||||
```json
|
||||
@@ -75,7 +75,17 @@ No remote import has been performed. Klaus owns account access. A browser login
|
||||
5. Run the same `apply PLAN --confirm-plan-sha256 HASH`. Before any data write, it reads authenticated Worker settings and requires `DB` and `PACKAGES` to match the target D1 ID and R2 bucket. It then verifies D1 registry identity/schema. The adapter uses the Cloudflare D1 query API and signed R2 S3 GET/conditional PUT (`If-None-Match: *`) on fixed account endpoints, with no arbitrary endpoint or unauthenticated admin route. It does not provision resources, change bindings or auto-migrate remote databases.
|
||||
6. Preserve the JSON receipt and verify official catalog/detail/filter, exact download bytes and compatible one-Install/graph/manage behavior on the actual stable HTTPS origin. Repeat provider redeployment/backup/restore acceptance independently before claiming durable delivery.
|
||||
|
||||
The remote HTTP request contract and binding mismatch were checked with a test transport, **not a live provider account**. Actual auth scopes, deployed binding shape, S3 condition handling, regional endpoints and provider limits still require verification. This adapter currently targets default R2 account endpoints; jurisdiction-specific endpoints require a reviewed configuration change. See [Worker settings API](https://developers.cloudflare.com/api/resources/workers/subresources/scripts/subresources/settings/methods/get/), [D1 query API](https://developers.cloudflare.com/api/resources/d1/subresources/database/methods/query/), and [R2 S3 compatibility](https://developers.cloudflare.com/r2/api/s3/api/).
|
||||
The legacy direct HTTP/S3 request contract and binding mismatch were checked with a test transport, **not a live provider account**. The new `hosted-ops.mjs` alternative reuses normal Wrangler OAuth and actual remote D1/R2 bindings instead of requiring separate S3 keys. Actual auth scopes, deployed binding shape, S3 condition handling, regional endpoints and provider limits still require verification. This adapter currently targets default R2 account endpoints; jurisdiction-specific endpoints require a reviewed configuration change. See [Worker settings API](https://developers.cloudflare.com/api/resources/workers/subresources/scripts/subresources/settings/methods/get/), [D1 query API](https://developers.cloudflare.com/api/resources/d1/subresources/database/methods/query/), and [R2 S3 compatibility](https://developers.cloudflare.com/r2/api/s3/api/).
|
||||
|
||||
## OAuth plan/apply alternative used for the hosted preview
|
||||
|
||||
Follow the environment/config guards in [Cloudflare hosting](cloudflare-hosting.md#supported-oauth-operator-and-provider-snapshots). Save the `result.target` returned by `hosted-ops.mjs inspect` as a target file. Generate the same reviewed plan with `official-cli.mjs plan TARGET ARTIFACT NEW_PLAN`, inspect its exact destination/provenance and SHA-256, then:
|
||||
|
||||
```sh
|
||||
node marketplace/cloudflare/hosted-ops.mjs apply marketplace/cloudflare/wrangler.deploy.json REVIEWED_CONFIG_SHA /absolute/plan.json REVIEWED_PLAN_SHA
|
||||
```
|
||||
|
||||
Both the local rehearsal and OAuth adapter call the same `validatePlan`/`importOfficial` functions. The OAuth path also verifies current 100% deployment bindings and `PUBLISHING_ENABLED=false`. It does not provision, grant auth, enable publication, reset storage or attach a hostname. Never use the placeholder config. A repeated apply is permitted only after actual state is checked; it returns `unchanged` when listing and stored bytes are identical.
|
||||
|
||||
## Executable acceptance
|
||||
|
||||
@@ -87,4 +97,4 @@ PLAYWRIGHT_MODULE=/absolute/path/to/playwright PATHAUTO_CORPUS=/absolute/pinned/
|
||||
|
||||
The browser test exports clean Pathauto source at `b97aadf47a37cff25f7d6105c3dade6778fccb47` into a disposable project. It uses the real CLI and local workerd/D1/R2, connects the browser once, clicks Install once, and verifies two route handlers, one hook and one service injection in actual SQLite. It proves malformed/incompatible/tampered failure preservation, disable/enable/remove cleanup, official catalog/detail/filter, and desktop/mobile layout. It does not modify the source corpus or rerun the larger corpus benchmark.
|
||||
|
||||
[Hosting/cost limits](cloudflare-hosting.md) remain unchanged: no durable Cloudflare URL, provider persistence, remote backup proof or Free-plan CPU fit is established. `marketplace.getcodegraph.com` remains proposed. The Drupal review evidence is recorded separately; historical measured rebuild overhead was 22–30%, and local rebuild timings do not establish Workers Free CPU suitability.
|
||||
See [supported OAuth operator, hosted proof and cost limits](cloudflare-hosting.md) for the dedicated stable HTTPS deployment and provider snapshot procedure. Free-plan CPU fit is not established by Paid-plan success. `marketplace.getcodegraph.com` remains proposed. The Drupal review evidence is recorded separately; historical measured rebuild overhead was 22–30%, and local rebuild timings do not establish Workers Free CPU suitability.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,103 @@
|
||||
# Cloudflare hosted preview acceptance — 2026-09-22
|
||||
|
||||
The dedicated [marketplace preview](https://codegraph-marketplace-preview.colby-7d9.workers.dev) now serves the actual frontend and API on Cloudflare Workers, backed by D1 and private R2. Official Drupal and community browser/CLI installation reached real local graphs over this stable HTTPS origin. Provider redeployment and a separate restore retained every release, owner and package. **Publishing is disabled on both endpoints.** This is a bounded preview acceptance, not a production release or a Free-plan certification.
|
||||
|
||||
The account already had Workers Paid. R2 Standard activation was separately approved and completed before this task. Supported Wrangler OAuth was reused without reading/copying credentials or touching the human browser. Only dedicated preview/restore resources were created. Existing telemetry/AI services, billing plan and DNS were not changed. `marketplace.getcodegraph.com` remains unconfigured.
|
||||
|
||||
## Revisions and implementation
|
||||
|
||||
Same draft [PR #1911](https://github.com/colbymchenry/codegraph/pull/1911). Worker source: `384daf329ff00c4bfb7bf874ea414f4f3cd121b1`; final operator: `c9b63f561099c08f74ed4b79ce8cd7f2b783f72c`; browser driver correction: `2b9ec85df61acabd21a29a47daf1b4b78bcd0a78`; read-only inventory source: `ad09aa5` (its previously exercised bytes are unchanged). Later changes are documentation, receipts and screenshots.
|
||||
|
||||
- `hosted-ops.mjs` uses supported Wrangler remote D1/R2 bindings with reviewed config/plan digests. It verifies the latest actual deployment's exact bindings and disabled-publication state. The provider's deployment list was observed oldest-first: sorting timestamps now prevents incorrectly admitting an old disabled deployment while a newer one permits publishing. Invalid/tied timestamps fail closed. A real active-window inspection was rejected before binding operations.
|
||||
- Official import reuses the existing pinned policy/provenance, conditional R2 object creation and atomic D1 ownership/release contract. No admin HTTP endpoint or separate S3 credential was added. Repeating the reviewed Drupal plan returned `unchanged` with the original timestamp and bytes.
|
||||
- Optional `PUBLISHING_UNTIL` makes a controlled publication window expire without another deployment; missing deadline preserves existing local fixture behavior. Health and POST share the same fail-closed deadline check. The actual hosted window used a UTC deadline, then was explicitly closed early.
|
||||
- `hosted-inventory.mjs` is read-only. It verifies referenced object sizes and reports all keys/bytes/orphans, independently of delayed bucket analytics.
|
||||
|
||||
The installed engine remains `7575dcc71e4524c660aff06486ebc007cca290b9`. Of the accepted semantic-update ledger, 25 source hashes and 12 compiled hashes still match; the two expected differences are documentation (`CHANGELOG.md`) and the Cloudflare Worker build. Engine/native/plugin source and both immutable Drupal packages are unchanged. Prior Linux **4,577 passed / 192 skipped / 284 files once**, Windows **162 / 4 skipped**, macOS **165 / 1 skipped**, and their recovery evidence remain at their original revisions. They were not rerun or presented as current-head CI. Automatic unrelated workflows were skipped for these hosting commits; affected runtime and real provider checks below were run explicitly.
|
||||
|
||||
## Actual deployment and storage
|
||||
|
||||
| Purpose | Worker version | State |
|
||||
|---|---|---|
|
||||
| Initial official import/browser | `ebd52779-28fc-4acb-9cfe-91c1e7bd1778` | Publishing disabled |
|
||||
| Bounded community/8 MiB acceptance | `3340394e-3bb7-4137-89ea-f38fd4de8d23` | Enabled 21:16–21:24 UTC; deadline 21:45:33 UTC |
|
||||
| Explicit close | `e5a0285b-250f-4254-907a-d3f37d4ed7cf` | Disabled |
|
||||
| Final replacement | `c0bdbbac-adcf-4609-aaf3-a69a380f3422` | Disabled, 100% deployment |
|
||||
| Separate restored preview | `15440b95-30e9-440e-bd82-d9a42d416a35` | Disabled; no main-origin cutover |
|
||||
|
||||
Main resources are `codegraph-marketplace-preview` / `codegraph-marketplace-preview-packages`. Restore resources are `codegraph-marketplace-preview-restore-20260922` / `codegraph-marketplace-preview-restore-20260922-packages`. Both databases are in WNAM, with read replication disabled. Both R2 buckets use Standard storage and have public `r2.dev` access disabled. The separate [restored endpoint](https://codegraph-marketplace-preview-restore-20260922.colby-7d9.workers.dev) serves verified restored bytes through its Worker. No public bucket, custom domain, lifecycle deletion, automatic cleanup or cutover was installed.
|
||||
|
||||
The private `wrangler.deploy.json`, `wrangler.window.json`, `wrangler.restore.json` and `../cloudflare-hosted-resources-20260922.json` retain actual account/resource IDs and config digests. These contain no credentials. Configured CPU limit is **1,000 ms/request**, unchanged across accepted versions. Actual bindings, limits and version IDs were read back using supported CLI tools. The checked-in placeholder config was never deployed.
|
||||
|
||||
## Acceptance results
|
||||
|
||||
| Check | Result and scope |
|
||||
|---|---|
|
||||
| Local real Worker runtime | **21 passed**, including immutable ownership, failure boundaries, process kills, backups, 8 MiB bytes and rate limits; final source `384daf3` |
|
||||
| Publication deadline | **4 passed**: future, expired, malformed, and live expiration without restart |
|
||||
| Operator guards | **18 passed**; plus actual active-window refusal and successful disabled-target admission |
|
||||
| Official Drupal HTTPS browser | **8 grouped checkpoints passed**, repeated after final redeployment |
|
||||
| Generated community compatibility | **10 passed**, **14 CLI commands**, including generated starter test/pack |
|
||||
| Community publisher/browser | **15 passed**, including real signing, ownership/signature/package failures, graph lifecycle, wrong origin/window and closed companion |
|
||||
| Provider package/security | 11 saved HTTP responses from interrupted command independently verified; continuation passed concurrent ownership winner and final immutable byte checks |
|
||||
| Provider redeploy/restore | All **17 releases**, **8 owners**, registry identity, recent nonces and **17 objects / 8,742,210 bytes** match across all three snapshots and HTTPS readbacks |
|
||||
|
||||
The official test exported pinned Pathauto `b97aadf47a37cff25f7d6105c3dade6778fccb47` into a separate owned directory. One connection and one Install selected official CodeGraph Drupal 0.1.1. Four exact SQLite links were asserted: settings route to form handler, bulk route to form handler, punctuation hook, and generator-to-cleaner injection. Disable/remove cleared contributions; enable restored them. Malformed/incompatible installs and test-injected downloaded-byte corruption preserved the working graph. The transport corruption was injected in the owned test client after downloading the real artifact; provider objects were not tampered with.
|
||||
|
||||
Compatibility published semantic versions out of publication order. The actual engine chose stable 1.10.0 over incompatible 9.0.0 and a preview; browser and CLI agreed. Explicit pins, preview opt-in, no-compatible selection, downgrade refusal, broken update rollback, successful update, exact URL/file semantics and cleanup passed. The generated extension produced its real Python event-to-handler edge. The separate publisher test used real browser signatures and actual postMessage boundaries. Its outage case intentionally aborted the owned browser request; the provider remained running. Earlier local stopped-service proof is retained separately.
|
||||
|
||||
The test catalog intentionally retains failed-attempt fixtures, incompatible versions and broken update fixtures; they are acceptance data, not recommendations. No resource or release was deleted to clean up the evidence.
|
||||
|
||||
[Desktop official proof](images/cloudflare-hosted-20260922/drupal-desktop.png) · [Mobile official proof](images/cloudflare-hosted-20260922/drupal-mobile.png) · [Compatible installation](images/cloudflare-hosted-20260922/compatible-desktop.png) · [Community cleanup](images/cloudflare-hosted-20260922/community-mobile.png). Captures were inspected. Desktop official capture shows installed 0.1.1 while compatibility refresh is pending; mobile capture shows selected and installed 0.1.1 explicitly.
|
||||
|
||||
## Provider persistence and backup
|
||||
|
||||
Publishing and operator writers were stopped before the snapshot. `backupRegistry` read all four metadata tables in one D1 batch, fetched each immutable referenced R2 object, validated package/identity/ownership/provenance and wrote `complete.json` last. Each snapshot was rechecked independently against its manifest and every object hash/size.
|
||||
|
||||
| Snapshot | `snapshot.json` SHA-256 |
|
||||
|---|---|
|
||||
| Before replacement | `d38e6451c183b2be450563efe727b9fdde9ca7661036facb9abc349883f9a207` |
|
||||
| After replacement | `1f2b3c74f4fee2ebed93219a422950be9740ceb9fc5d6bddbdbbd97713b4ab2f` |
|
||||
| Re-export from restored pair | `85cb4da7982f4095433c55cc83957454dfe781b3d653b38bd6410831ea6c1635` |
|
||||
|
||||
Snapshot hashes differ because creation times differ; **all table bodies and object bytes are identical**. Restore used a newly created/migrated pair, verified the restore Worker was absent, refused live/occupied targets, uploaded bytes first and committed metadata in one D1 batch. Only after success was its read-only Worker deployed. Every version was then downloaded through both HTTPS endpoints and compared with the original reference. Binding inventories found no orphan objects in either bucket.
|
||||
|
||||
Copies remain under `.qa/hosted/backups/` and in the private recovery archive. The restored provider pair is independent of the live bindings but is in the same account. This is not off-account disaster recovery. Independent off-site retention, automated backup scheduling, RPO/RTO and an approved teardown policy remain open. Seven daily/four weekly snapshots are a documented proposal only.
|
||||
|
||||
## Deployed CPU, memory observations and cost limits
|
||||
|
||||
Actual provider trace fields were captured, then filtered to remove request headers/IP/TLS metadata. The final captured window has **262 invocations**, **1,168 total CPU-ms**, zero execution exceptions and all `outcome=ok`. HTTP outcomes include expected 400/403/503 validation/disabled responses; “ok” does not mean every request was accepted. This sample is not complete account usage or a load test.
|
||||
|
||||
| Operation | CPU measurement |
|
||||
|---|---|
|
||||
| Accepted 8,388,608-byte signed publication | **379 ms**, one sample; 1,435 ms provider wall time |
|
||||
| Three immediate full package downloads | **22 / 26 / 20 ms**, all hashes/lengths equal |
|
||||
| Oversized-by-one-byte rejection | **197 ms**, one sample |
|
||||
| Small accepted publications captured | **5–10 ms**, eight samples, median 8 ms |
|
||||
| Catalog/detail reads captured | **0–9 ms**, 182 samples, median 1 ms |
|
||||
|
||||
These Paid-plan measurements exceed the [Free 10 ms CPU limit](https://developers.cloudflare.com/workers/platform/limits/) for the full package contract. **Do not select Free for this implementation based on this proof.** No Free deployment or plan change was attempted. The 1,000 ms configured cap comfortably covered these samples, not arbitrary sustained traffic.
|
||||
|
||||
The actual trace exposes CPU/wall/outcome, **not a heap high-water measurement**. No sampled `exceededMemory` event occurred. The platform's 128 MB per-isolate limit is not measured consumption; concurrent large uploads/downloads and memory headroom remain unverified. A precise deployed peak-memory result could not be obtained through the available supported trace interface.
|
||||
|
||||
Dedicated D1 readback: 94,208 bytes each; main 24h counters reported 1,750 rows read / 217 written, restored 222 / 146 at observation time. R2 CLI analytics lagged and reported zero objects/bytes, despite strongly consistent binding lists and successful byte reads showing 17 objects / 8,742,210 bytes each. Delayed counters were retained, not substituted for evidence.
|
||||
|
||||
The existing [Workers Paid plan](https://developers.cloudflare.com/workers/platform/pricing/) has a $5 monthly minimum plus applicable overages; no incremental zero-cost promise is made. [D1](https://developers.cloudflare.com/d1/platform/pricing/) and [R2](https://developers.cloudflare.com/r2/pricing/) allowances and charges are account-wide. Existing telemetry storage/other apps, backup copies, logs, verification requests and abuse count. Rate limits and a per-request CPU cap are not a hard spending cap. The measured sample and small inventory do not forecast monthly demand. No additional billing activation or subscription change occurred in this task.
|
||||
|
||||
## Retained failures and interruptions
|
||||
|
||||
- Combined Wrangler migration apply returned `SQLITE_ERROR: incomplete input`. Actual schema inspection showed only the migration ledger; the same unchanged migration statements subsequently passed via supported remote D1 transactional batches. No reset or weakened SQL was used.
|
||||
- Remote-binding setup initially attempted a registry directory outside this sandbox. Required permitted retries are preserved. Both documented registry-path variables now point to the owned workspace; credentials were never inspected. A pre-migration read correctly failed for absent schema.
|
||||
- First dry run used an incorrect output directory; the corrected absolute directory passed. One read accidentally used an incorrect version ID and returned not-found; the actual deployment ID was then read back. Neither changed provider state.
|
||||
- Two hosted browser harness attempts failed (detail-page project selector, then duplicate catalog links). Both remain in receipts/screenshots; final selectors passed with a new immutable fixture ID. No application assertion was weakened.
|
||||
- The original package command was terminated by the tool with exit **143**, cause unknown, after 11 completed response receipts. It has no final command receipt. The explicit continuation verified every saved status/error/hash, finished the missing concurrent claim check and re-read original bytes. No uninterrupted pass is claimed and the large upload was not repeated.
|
||||
- The first tail was intentionally stopped; a second tail ended with tool **143**, cause unknown; the final tail was intentionally stopped with **130** after capture. An early operator inspection was stopped after its registry-path failure. Started receipts and raw logs remain. Expected not-found/active-publishing refusals are distinct from test failures.
|
||||
- The evidence-builder first attempt had a local `Path` naming error after its assertions; fixed without changing provider state. Both historical core/previous Linux interruptions remain documented in their original reports.
|
||||
|
||||
The [JSON ledger](extensions-cloudflare-hosted-20260922.json) pins source/build hashes, exact command bodies/exits, raw files, config digests, provider versions, results and snapshots. Raw tail data is not published; raw tail evidence is private, and Wrangler auth/debug/dev-registry files are excluded from the recovery archive. No merge, release or npm publication occurred.
|
||||
|
||||
## Decision and remaining gates
|
||||
|
||||
**Pass for a dedicated read-only hosted preview on the existing Paid plan.** Stable Worker HTTPS, real local graph installation, immutable ownership, provider redeployment and detached backup/restore have actual evidence. General publication remains disabled.
|
||||
|
||||
Before production or broader traffic: establish memory/concurrency headroom and account usage alerting, independent backup retention/RPO/RTO, catalog pagination beyond the 1,000-release preview cap, authorized fixture cleanup and release/distribution policy. Custom domain is separate authorization. No selective semantic skipping is enabled: the accepted shadow no-go and its metadata/lifecycle/economics gaps remain. Global graph costs, mixed warm/cold results, higher core RSS and historical 22–30% Drupal rebuild overhead remain in the prior reports. Product completion remains partial.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 78 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 104 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 105 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 120 KiB |
Reference in New Issue
Block a user