CoreHub write-side records are the planned marketplace control plane for publisher accounts, package submissions, managed artifact uploads, moderation reviews, ownership transfers, and install analytics.
The public Registry API v1 remains read-only. The write-side schema is a separate contract so CoreHub can add authenticated publishing without changing the existing catalog read shape.
The schema follows the ClawHub pattern where publishing is owner-scoped:
- A publisher owns a package namespace.
- A submission targets one publisher, package id, and version.
- The server validates owner permission, package scope, artifact metadata, and source attribution.
- A release remains hidden from install/download surfaces until review approves it.
- Moderation can block or deprecate versions without rewriting package history.
| Collection | Purpose |
|---|---|
authSessions |
Authenticated CLI or API sessions for publisher workflows. |
userAccounts |
Signed upstream GitHub account identities linked to personal publishers. |
publisherClaims |
Handle reservation and verification requests before an account is active. |
publisherAccounts |
Stable publisher handles for users or organizations. |
publisherMembers |
Role bindings for organization-owned publishers. |
packageSubmissions |
Authenticated publish attempts before they become public versions. |
packageVersions |
Immutable package version records after review. |
artifactUploads |
Managed upload metadata, storage locator, size, checksum, file manifest, and npm artifact metadata. |
moderationReviews |
Human or automated review decisions. |
ownershipTransfers |
Explicit publisher ownership moves with audit history. |
trustedPublishers |
GitHub Actions trusted publisher policy per package. |
publishTokens |
Short-lived CI publish tokens minted from trusted publisher policy. |
installEvents |
Privacy-preserving aggregate install and verification events. |
auditEvents |
Operator audit trail for write-side actions and admin reads. |
auditRetentionCheckpoints |
Export-before-prune checkpoints for archived audit prefixes. |
auth session -> publisher claim -> publisher account -> package submission -> artifact upload -> moderation review -> package version -> install event
Submissions start as draft or pending_review. Only approved submissions can create an available package version. Blocked, rejected, or held records must not become installable.
The write-side schema does not replace corehub.catalog.schema.json.
| Surface | Contract |
|---|---|
corehub.catalog.schema.json |
Public read-only catalog consumed by web, API v1, and current CLI reads. |
corehub.write-side.schema.json |
Authenticated marketplace state for future write-side APIs. |
Public API v1 can continue to project approved packageVersions and verified artifactUploads into the existing catalog shape.
CoreHub API v2 now resolves a request actor from the authenticated CLI headers and checks publisher membership before accepting write-side mutations.
| Boundary | Required permission |
|---|---|
GET /corehub/api/v2/publishers/me |
Any authenticated actor; returns memberships, roles, default publisher, and derived permissions. |
POST /corehub/api/v2/oauth/github/start |
Starts a GitHub browser OAuth exchange and returns a signed state plus provider authorization URL. |
GET /corehub/api/v2/oauth/github/callback / POST /corehub/api/v2/oauth/github/exchange |
Exchanges a GitHub OAuth code, fetches the GitHub user profile, mints a signed CoreHub browser session token, stores the account, and bootstraps a personal publisher. |
POST /corehub/api/v2/oauth/github/complete |
Completes a CoreBlow/CoreHub-signed upstream GitHub identity for trusted app-boundary integrations and tests. |
GET /corehub/api/v2/account/me |
Returns the signed-in account, actor, publisher identity, memberships, and default publisher. |
PATCH /corehub/api/v2/account/me |
Updates self-service profile fields and audits user.profile.update. |
DELETE /corehub/api/v2/account/me |
Soft-deletes the signed-in account, revokes active sessions, removes memberships, and audits user.account.delete. |
POST /corehub/api/v2/orgs |
Creates a verified organization publisher for a signed-in account and assigns the actor as owner. |
PATCH /corehub/api/v2/orgs/:handle |
Updates organization profile/settings fields and audits publisher.profile.update. |
DELETE /corehub/api/v2/orgs/:handle |
Soft-deletes an organization publisher after explicit confirmation. |
GET /corehub/api/v2/orgs/:handle/members |
Lists organization publisher members for owners, admins, or global admins. |
POST /corehub/api/v2/orgs/:handle/members |
Adds or updates an organization member role. |
POST /corehub/api/v2/orgs/:handle/invites |
Creates or refreshes an invited member by GitHub login, user id, or email. |
POST /corehub/api/v2/orgs/:handle/invites/accept |
Lets a matching signed-in actor accept an organization invite. |
DELETE /corehub/api/v2/orgs/:handle/members/:userId |
Removes an organization member without deleting account history. |
POST /corehub/api/v2/artifacts/uploads |
Active owner, admin, or maintainer membership on the requested publisherHandle. |
POST /corehub/api/v2/artifacts/uploads/:id/verify |
Active write membership on the upload slot publisher. |
POST /corehub/api/v2/submissions |
Active write membership on the submission publisher. |
GET /corehub/api/v2/submissions* |
Admin or moderator actor. |
GET /corehub/api/v2/reviews* |
Admin or moderator actor. |
POST /corehub/api/v2/reviews/:id/assign |
Admin or moderator actor. |
POST /corehub/api/v2/reviews/:id/evidence |
Admin or moderator actor. |
POST /corehub/api/v2/reviews/:id/approve |
Admin or moderator actor. |
POST /corehub/api/v2/reviews/:id/block |
Admin or moderator actor. |
GET /corehub/api/v2/audit/* |
Admin or moderator actor. |
POST /corehub/api/v2/audit/retention/prune |
Admin or moderator actor plus export-before-prune evidence. |
GET /corehub/api/v2/admin/status |
Admin or moderator actor; returns state store, object store, queue, analytics, audit, and readiness status. |
GET /corehub/api/v2/admin/support-bundle |
Admin or moderator actor; exports a redacted operator support bundle. |
The signed upload PUT /corehub/api/v2/artifacts/uploads/:id remains a capability-style upload boundary. It validates the reserved slot, expected checksum, media type, and byte limits; publisher authorization happens when the slot is requested and when the uploaded artifact is verified.
Default local bootstrap seeds github:coreblow-admin as the coreblow owner and admin actor so existing local smoke flows remain deterministic. Production operators can set COREHUB_ADMIN_ACTORS to the comma-separated admin or moderator actor ids allowed to review, inspect queues, and read audit evidence.
The future authenticated API should expose these resources under a new versioned write surface:
| Endpoint | Purpose |
|---|---|
POST /corehub/api/v2/publishers |
Reserve or claim a publisher handle. |
GET /corehub/api/v2/publishers/me |
Show the current actor's publisher memberships. |
POST /corehub/api/v2/artifacts/uploads |
Request a managed artifact upload slot. |
PUT /corehub/api/v2/artifacts/uploads/:id |
Upload artifact bytes with signed request metadata. |
POST /corehub/api/v2/artifacts/uploads/:id/verify |
Verify uploaded bytes against expected size and checksum. |
POST /corehub/api/v2/submissions |
Create a package submission from uploaded artifact metadata. |
GET /corehub/api/v2/submissions/:id |
Inspect submission status and review diagnostics. |
POST /corehub/api/v2/reviews/:id/assign |
Assign an open or held review to a moderator actor. |
POST /corehub/api/v2/reviews/:id/evidence |
Add moderation evidence such as manual notes, scan links, or policy findings. |
POST /corehub/api/v2/reviews/:id/approve |
Approve a submission or version for install surfaces. |
POST /corehub/api/v2/reviews/:id/block |
Block a submission, version, artifact, or publisher. |
GET /corehub/api/v2/transfers |
List package ownership transfer requests with status and package filters. |
GET /corehub/api/v2/transfers/:id |
Inspect one ownership transfer and current package owner. |
POST /corehub/api/v2/transfers |
Request package ownership transfer from the current publisher to a verified target publisher. |
POST /corehub/api/v2/transfers/:id/accept |
Target publisher accepts and completes ownership transfer. |
POST /corehub/api/v2/transfers/:id/reject |
Target publisher or admin rejects ownership transfer. |
POST /corehub/api/v2/transfers/:id/cancel |
Source publisher cancels a pending transfer. |
DELETE /corehub/api/v2/packages/:id |
Soft-delete all published versions for a package. |
POST /corehub/api/v2/packages/:id/undelete |
Restore soft-deleted package versions. |
GET /corehub/api/v2/session/validate |
Validate a token-backed browser session for the requested admin or publisher role before loading privileged UI data. |
GET /corehub/api/v2/package-scans |
List static package scan jobs with status, package, and version filters. |
POST /corehub/api/v2/package-scans/backfill |
Backfill missing static scan jobs for available package versions. |
POST /corehub/api/v2/packages/:id/scans/rescan |
Run a new static scan job for one package version. |
GET /corehub/api/v2/audit/events |
List write-side audit events with target, action, actor, and pagination filters. |
GET /corehub/api/v2/audit/verify |
Verify the append-only audit hash chain and return the current head hash. |
GET /corehub/api/v2/audit/retention |
Inspect retention policy, prune cutoff, and integrity failure behavior. |
POST /corehub/api/v2/audit/retention/prune |
Prune only after an operator export hash is supplied. |
POST /corehub/api/v2/install-events |
Record opt-in, privacy-preserving install telemetry. |
GET /corehub/api/v2/install-events/summary |
Return admin aggregate install analytics by package, version, event, source, and day. |
GET /corehub/api/v2/admin/status |
Return one operator status document for state store, object store, queue counts, transfer counts, install analytics, audit integrity, and readiness. |
GET /corehub/api/v2/admin/support-bundle |
Return the same status plus redacted recent queue and audit samples for support escalation. |
Public Registry API v1 and npm mirror errors are ClawHub-compatible plain text responses. 400, 401, 403, 404, 429, and blocked downloads use content-type: text/plain; charset=utf-8; clients should read the body as a human-readable reason. Rate-limited public responses include Retry-After and the X-RateLimit-* plus RateLimit-* headers.
Authenticated API v2 errors use a stable JSON envelope while preserving the legacy error string for existing UI and CLI callers:
{
"apiVersion": "v2",
"error": "Not found",
"errorCode": "not_found",
"status": 404,
"message": "Not found"
}Known errorCode values include bad_request, invalid_cursor, unauthorized, forbidden, blocked_download, not_found, conflict, payload_too_large, unsupported_media_type, rate_limited, unavailable, and internal_error.
Future CLI commands should keep the ClawHub-style dry-run habit:
corehub publisher login
corehub publisher whoami
corehub package upload request ./plugin-lab.coreblow-plugin.tgz --dry-run
corehub package upload verify ./plugin-lab.coreblow-plugin.tgz --upload-slot upload-plugin-lab-0-1-0 --dry-run
corehub package submit ./plugin --dry-run
corehub package submit ./plugin-lab.coreblow-plugin.tgz --dry-run
corehub package submit ./plugin-lab.coreblow-plugin.tgz --registry https://coreblow.com/corehub --dry-run
corehub transfers request plugin-lab --to example-org --registry https://coreblow.com/corehub
corehub transfers accept transfer-plugin-lab-coreblow-to-example-org --registry https://coreblow.com/corehub
corehub analytics record plugin-lab --version 0.1.0 --event installed --source cli --registry https://coreblow.com/corehub
corehub analytics summary --package plugin-lab --registry https://coreblow.com/corehub
corehub admin status --registry https://coreblow.com/corehub
corehub admin support-bundle --output ./corehub-support-bundle.json --registry https://coreblow.com/corehub
corehub package publish ./plugin --dry-run
corehub package publish ./plugin --registry https://coreblow.com/corehub
corehub package submit ./plugin-lab.coreblow-plugin.tgz
corehub package transfer request plugin-lab --to coreblowPublishing should fail closed when package scope, publisher ownership, artifact checksum, trusted-publisher policy, official-channel policy, or moderation status cannot be verified. A live publish creates a pending review submission; approval remains a separate moderator/admin action.
CoreHub separates upload storage from submission review. A publisher first requests a managed upload slot, uploads bytes with signed metadata, then asks CoreHub to verify the uploaded artifact before a package submission can reference it.
| Step | Contract |
|---|---|
| Request upload slot | CLI or API resolves actor, publisher, package id, version, media type, size, and expected SHA-256. |
| Signed upload metadata | CoreHub returns method, URL, expiry, max byte limit, required headers, storage locator, and signature. |
| Upload bytes | Client uploads the exact artifact to the reserved storage locator. |
| Verify checksum | CoreHub reads the stored object metadata or bytes and compares size and SHA-256 before marking the artifact verified. |
| Submit package | Submission references only a verified artifact upload id. |
The dry-run CLI shape is:
corehub package upload request ./plugin-lab.coreblow-plugin.tgz --dry-run
corehub package upload verify ./plugin-lab.coreblow-plugin.tgz --upload-slot upload-plugin-lab-0-1-0 --dry-run
corehub package upload request ./plugin-lab.coreblow-plugin.tgz --registry https://coreblow.com/corehub --dry-run
corehub package upload verify ./plugin-lab.coreblow-plugin.tgz --upload-slot upload-plugin-lab-0-1-0 --registry https://coreblow.com/corehub --dry-runartifactUploads[].upload records the signed upload contract used for a managed object. artifactUploads[].files and artifactUploads[].npm preserve the file manifest, integrity, shasum, tarball name, unpacked size, and file count that are projected into public package versions. The public catalog should only expose verified artifact locators, checksums, manifests, and npm metadata, not write-side upload signatures.
When --registry is provided, the CLI uses the API v2 upload boundary. Without --registry, it keeps the local dry-run fallback so publishers can inspect the planned payload before the hosted write API is available.
corehub package submit <artifact> --registry <url> --dry-run uses the verified artifact upload id for the package and version. A custom id can be passed with --artifact-upload <id> when the upload slot does not follow the default artifact-<package>-<version> shape.
Ownership transfer moves the effective package owner for future submissions without rewriting historical package versions.
| Step | Contract |
|---|---|
| Request | Source publisher owner, admin, or maintainer calls POST /corehub/api/v2/transfers with packageId, fromPublisherHandle, and verified toPublisherHandle. |
| Accept | Target publisher owner, admin, or maintainer accepts the pending transfer. CoreHub marks it completed and future submissions must use the target publisher. |
| Reject | Target publisher or CoreHub admin rejects the pending transfer. |
| Cancel | Source publisher cancels the pending transfer before acceptance. |
| Audit | Every request, accept, reject, cancel, list, and inspect action records an ownership.transfer.* audit event. |
The CLI shape is:
corehub transfers request plugin-lab --to example-org --registry https://coreblow.com/corehub --reason "Move to org publisher."
corehub transfers list --status requested --package plugin-lab --registry https://coreblow.com/corehub
corehub transfers inspect transfer-plugin-lab-coreblow-to-example-org --registry https://coreblow.com/corehub
corehub transfers accept transfer-plugin-lab-coreblow-to-example-org --registry https://coreblow.com/corehub --notes "Accepted."
corehub transfers reject transfer-plugin-lab-coreblow-to-example-org --registry https://coreblow.com/corehub --notes "Rejected."
corehub transfers cancel transfer-plugin-lab-coreblow-to-example-org --registry https://coreblow.com/corehub --notes "Cancelled."Install analytics is opt-in and privacy-preserving. CoreHub records aggregate lifecycle events without storing raw IP addresses, raw user agents, or client identifiers. When a client id is provided, the server stores only a salted SHA-256 hash.
| Field | Privacy behavior |
|---|---|
packageId, version, publisherHandle |
Required package-level aggregation keys. |
event |
One of resolved, downloaded, verified, installed, blocked, or failed. |
source |
One of cli, coreblow, api, or ci. |
day |
UTC day bucket derived from server time. |
clientHash |
Optional salted hash of client id; raw client id is discarded. |
The API shape is:
POST /corehub/api/v2/install-events
GET /corehub/api/v2/install-events/summary?package=plugin-labThe CLI shape is:
corehub analytics record plugin-lab --version 0.1.0 --event installed --source cli --client-id local-client --registry https://coreblow.com/corehub
corehub analytics summary --package plugin-lab --registry https://coreblow.com/corehubAdmin visibility is the operator-facing read boundary for production support. It does not mutate marketplace state, but every read is audit logged so enterprise operators can prove who inspected the control plane.
| Command | Purpose |
|---|---|
corehub admin status |
Shows state store kind, object store kind, queue counts, transfer counts, install analytics totals, audit integrity, retention policy, and deploy readiness. |
corehub admin health |
Alias for corehub admin status for operational runbooks. |
corehub admin support-bundle --output file |
Exports a redacted JSON support bundle with recent submissions, reviews, transfers, and audit events. |
The support bundle intentionally omits signing secrets, raw client identifiers, raw IP addresses, and raw user agents.
Phase 18 adds the server-side shape for artifact references. The API handler accepts the same write-side payload that the CLI dry run emits. In production external-url mode, it records a verified artifact URL reference with size and SHA-256 metadata so CoreHub can moderate and publish without paid object storage. Managed byte storage remains a local test path only.
| Route | Behavior |
|---|---|
POST /corehub/api/v2/artifacts/uploads |
Validates publisher, package, artifact metadata, optional file manifest, optional npm metadata, expected size, expected SHA-256, storage provider, max byte limit, and optional artifact URL, then returns an upload slot. External URL providers are marked verified by reference. |
POST /corehub/api/v2/package-scans/enqueue |
Queues a hosted CoreHub ClawScan or VirusTotal package scan with artifact metadata, package context, and audit evidence. |
POST /corehub/api/v2/package-scans/:id/result |
Records hosted scanner callback results, provider analysis snapshots, reason codes, risk level, evidence, and the resolved public scan trust state. |
PUT /corehub/api/v2/artifacts/uploads/:id |
Accepts artifact bytes for managed storage slots and writes them through the configured storage adapter. |
POST /corehub/api/v2/artifacts/uploads/:id/verify |
Reads the managed stored object, recomputes size and SHA-256, and returns a verified or rejected artifact upload record. |
POST /corehub/api/v2/submissions |
Accepts a verified artifact upload id and creates a pending-review package submission. |
POST /corehub/api/v2/package-reports |
Accepts a package report tied to a published package version and records it for moderation intake. |
GET /corehub/api/v2/package-reports |
Lists package reports for moderators and admins with status, package, and pagination filters. |
POST /corehub/api/v2/package-reports/:id/triage |
Records a moderator/admin triage decision, note, and optional final action. |
POST /corehub/api/v2/package-appeals |
Accepts a publisher appeal for a published package version and records it as a separate moderation queue item. |
GET /corehub/api/v2/package-appeals |
Lists package appeals for moderators and admins with status, package, and pagination filters. |
POST /corehub/api/v2/package-appeals/:id/resolve |
Records a moderator/admin appeal resolution, note, and optional final action. |
DELETE /corehub/api/v2/packages/:id |
Soft-deletes all published versions for the package and removes it from Registry API v1 projections. |
POST /corehub/api/v2/packages/:id/undelete |
Restores soft-deleted package versions and makes the package visible to Registry API v1 projections again. |
GET /corehub/api/v2/packages/:id/trusted-publisher |
Reads the package trusted publisher policy for owners, members, admins, and moderators. |
PUT /corehub/api/v2/packages/:id/trusted-publisher |
Sets GitHub Actions trusted publisher policy for a package owner or admin. |
DELETE /corehub/api/v2/packages/:id/trusted-publisher |
Removes trusted publisher policy without deleting package history. |
POST /corehub/api/v2/packages/:id/publish-tokens |
Mints a short-lived publish token for a matching trusted publisher workflow run. When oidcToken is present, CoreHub verifies the GitHub Actions OIDC JWT before minting. |
POST /corehub/api/v2/packages/:id/publish-tokens/:tokenId/revoke |
Revokes a short-lived publish token and records the revocation audit event. |
POST /corehub/api/v2/reviews/:id/approve |
Approves a pending submission review and creates an available package version. |
POST /corehub/api/v2/reviews/:id/block |
Blocks a pending submission review and creates a blocked package version record for audit visibility. |
GET /corehub/api/v1/packages/:id/download |
Returns signed read metadata, or redirects to a signed read URL by default. |
GET /corehub/api/v1/artifacts/read |
Reads the stored artifact through CoreHub after validating signature, expiry, size, and SHA-256. |
Signed read URLs use HMAC signatures from COREHUB_SIGNING_SECRET and include a keyId so operators can stage rotation with COREHUB_SIGNING_PREVIOUS_SECRETS. Download signing and successful reads are recorded as artifact.download.sign and artifact.download.read audit events.
Each remote submission receives an open moderation review id with starter evidence for artifact checksum and source attribution. Review queue work is explicit:
| Action | Effect |
|---|---|
assign |
Stores assignee, assignedBy, and assignedAt on the review. |
evidence add |
Appends typed evidence with summary, metadata, actor, and timestamp. |
approve |
Marks submission approved and creates an installable package version. |
block |
Marks submission rejected and creates a blocked, non-installable package version. |
Review decisions are explicit write-side events:
| Decision | Submission result | Package version result |
|---|---|---|
approve |
approved |
available with moderationStatus: approved |
block |
rejected |
blocked with moderationStatus: blocked |
Review approval is the first point where a submitted artifact can become installable. Blocked versions remain non-installable but auditable, preserving package/version history instead of deleting the failed submission.
Package reports are separate from submission reviews. A report does not hide or block a package by itself; it becomes an auditable moderation intake record until a moderator triages it as confirmed, dismissed, or reopened as open. When a confirmed report carries final action quarantine or revoke, CoreHub applies release moderation to the affected version, marks it download-blocked in trust metadata, and returns 403 from package download routes.
Package appeals are separate from package reports. A verified publisher can appeal a published version with a message, and a moderator resolves the appeal as accepted, rejected, or reopened as open with optional final action none or approve.
Package delete and undelete are soft lifecycle operations. Delete marks package versions with softDeletedAt, records the actor and optional reason, disables artifact download in state, and hides the package from Registry API v1. Undelete clears the soft-delete marker, records restore metadata, and makes the package visible again without rewriting submission, review, or audit history.
Trusted publisher policy lets a package owner bind a package to one GitHub Actions repository, workflow filename, and optional environment. Short-lived publish tokens can only be minted when the requested repository, workflow, and environment match that policy. With corehub package publish-token mint --oidc, CoreHub verifies the GitHub Actions OIDC JWT issuer, audience, RS256 signature, expiry, repository, workflow filename, environment, run id, run attempt, SHA, and ref before minting. Official-channel submissions fail closed unless the actor is an admin or supplies a matching trusted publisher token, and manual submissions against a trusted-publisher package require a manual override reason.
The trusted publisher CLI shape is:
corehub package trusted-publisher set plugin-lab --repository coreblow/plugin-lab --workflow publish.yml --registry http://127.0.0.1:8787/corehub
corehub package trusted-publisher get plugin-lab --registry http://127.0.0.1:8787/corehub
corehub package publish-token mint plugin-lab --version 0.2.0 --oidc --registry http://127.0.0.1:8787/corehub
corehub package publish-token revoke plugin-lab --token-id publish-token-plugin-lab-0-2-0-000001 --registry http://127.0.0.1:8787/corehubThe admin CLI can now call these API v2 review decisions:
corehub review approve review-plugin-lab-0-1-0 --registry http://127.0.0.1:8787/corehub --notes "Artifact verified."
corehub review block review-plugin-lab-0-1-0 --registry http://127.0.0.1:8787/corehub --notes "Blocked by moderation."
corehub review assign review-plugin-lab-0-1-0 --to moderator:corehub --registry http://127.0.0.1:8787/corehub
corehub review evidence add review-plugin-lab-0-1-0 --type manual_note --summary "Source and checksum verified." --registry http://127.0.0.1:8787/corehubThe current adapter is local and mocked for tests. Its storage key shape is already compatible with managed object storage:
uploads/<publisher>/<package>/<version>/<artifact>
Production Worker binding uses COREHUB_OBJECT_STORE=external-url, so no paid object-storage binding is required and package artifacts are referenced by URL plus checksum metadata. Local server bootstrap still uses filesystem storage for deterministic development and CI. The route contract, signed upload fields, checksum verification result, and artifact upload status graph remain stable.
Approved write-side versions can now be projected into the read-only Registry API v1 shape through the persistence adapter boundary:
verified artifact upload -> pending submission -> approved review -> available package version -> projected catalog entry
The local projection exposes approved package versions through the same public read contracts used by existing clients:
| Route | Projection behavior |
|---|---|
GET /corehub/api/v1/entries |
Returns projected catalog entries for approved versions only. |
GET /corehub/api/v1/packages/:id |
Returns the projected package entry. |
GET /corehub/api/v1/packages/:id/versions |
Returns projected available versions. |
GET /corehub/api/v1/packages/:id/artifact |
Returns artifact checksum, storage locator, and non-download metadata. |
Blocked versions remain write-side audit records and are intentionally excluded from projected v1 install/search surfaces.
The local storage adapter preserves one logical corehub.local-state.v1 model across local JSON and D1. Local development persists that model as a JSON file. Production D1 persists the same logical model as normalized meta rows, collection rows, and lookup index rows, while keeping legacy snapshot fallback reads for migration safety.
| State section | Contents |
|---|---|
slots |
Upload slots, signed upload metadata, expected artifact checksum, and artifact upload status. |
submissions |
Package submission records plus pending or decided package version previews. |
reviews |
Moderation review decisions and reviewer audit metadata. |
packageVersions |
Approved, blocked, soft-deleted, or restored version records used by projection. |
packageSearchDigests |
Digest-backed public search/list rows rebuilt from package projections, including filter fields, tokens, scan status, and public entry payload. |
skillVersions |
Hosted skill versions with text files, rendered SKILL.md, static security scan summary, publisher owner, and lifecycle state. |
skillSearchDigests |
Digest-backed hosted skill search/list rows with public entry payloads, capability tags, scan status, and search tokens. |
communityStars |
User stars for package and hosted skill targets, with idempotent active/removed state. |
communityComments |
Visible, hidden, or deleted community comments attached to package and hosted skill targets. |
communityCommentReports |
Abuse reports for comments, used for moderation intake and auto-hide thresholds. |
trustedPublishers |
Package-level trusted publisher policies. |
publishTokens |
Short-lived CI publish tokens with mint, use, and revoke metadata. |
packageReports |
Package moderation reports and triage metadata. |
packageAppeals |
Publisher appeals and moderator resolution metadata. |
packageScanJobs |
Static scanner job status and evidence records. |
auditEvents |
Append-only audit events for upload, verification, submission, review decision, and admin read actions. |
auditCheckpoints |
Local checkpoint records created after export-before-prune retention actions. |
The D1 normalized store indexes package/version, skill slug, community targets, comment ids, status, publisher, scan result, repository, audit sequence, target, day, install event, marketplace filter fields, capability tags, and search tokens. This gives CoreHub a ClawHub-like table/index persistence shape without leaking D1 storage details into the HTTP API or CLI.
Community moderation is an admin-facing API v2 surface. GET /corehub/api/v2/community/comment-reports lists comment report queue entries with the comment snapshot, target stats, and reporter profile. POST /corehub/api/v2/community/comment-reports/:id/resolve records a reviewed/closed resolution and can apply hide, unhide, or none action to the comment. GET /corehub/api/v2/community/signals summarizes publisher profile signals and package/skill leaderboards for the admin UI.
CoreHub records audit events in the same spirit as ClawHub's general auditLogs and moderation event logs. Each event includes id, sequence, actor, action, targetType, targetId, metadata, createdAt, previousHash, and eventHash.
The audit trail is lightly tamper-evident. Every event hashes a canonical payload that includes its sequence number and the previous event hash. The first event uses 64 zeroes as previousHash, and corehub audit verify recomputes the chain to prove the current log has not been edited out of order.
Retention is fail-closed. If the chain is invalid, CoreHub blocks pruning and tells operators to export the current state and escalate. When retention pruning is allowed, the operator must export first; CoreHub records a checkpoint with the pruned prefix head hash and export hash so the remaining chain can still be verified.
The local API currently records:
| Action | Target |
|---|---|
artifact.upload.request |
Managed artifact upload id. |
artifact.upload.put |
Managed artifact upload id. |
artifact.upload.verify |
Managed artifact upload id. |
submission.create |
Package submission id. |
review.approve / review.block |
Moderation review id. |
submission.list / submission.inspect |
Submission queue or submission id. |
review.list / review.inspect |
Review queue or review id. |
audit.list |
Audit query target or filter. |
audit.verify |
Audit chain verification read. |
audit.retention.inspect |
Retention policy and prune plan read. |
audit.retention.prune |
Export-backed retention prune checkpoint. |
package.trusted_publisher.set / package.trusted_publisher.delete |
Package id. |
package.publish_token.mint / package.publish_token.use / package.publish_token.revoke |
Publish token id. |
Operators can inspect the trail through the read-only CLI surface:
corehub audit list --target review-plugin-lab-0-1-0 --limit 20 --registry http://127.0.0.1:8787/corehub
corehub audit list --action review.approve --limit 20 --registry http://127.0.0.1:8787/corehub
corehub audit list --action review.approve --actor github:coreblow-admin --target-type review --format jsonl --output ./review-approvals.audit.jsonl --registry http://127.0.0.1:8787/corehub
corehub audit verify --registry http://127.0.0.1:8787/corehub
corehub audit incident report --format markdown --output ./audit-incident.md --registry http://127.0.0.1:8787/corehub
npm run audit:incident -- --registry http://127.0.0.1:8787/corehub --output ./audit-incident.md
corehub audit retention --dry-run --registry http://127.0.0.1:8787/corehub
corehub audit retention --prune --output ./audit-retention.audit.jsonl --registry http://127.0.0.1:8787/corehubFor enterprise export examples, see docs/audit-runbook.md. For fail_closed handling, see docs/audit-incident-response.md.
Phase 24 adds a production-ish local API server entrypoint:
npm run serveDefaults:
| Setting | Default |
|---|---|
COREHUB_HOST |
127.0.0.1 |
COREHUB_PORT |
8787 |
COREHUB_DATA_ROOT |
.corehub-local |
COREHUB_STATE_PATH |
.corehub-local/write-side-state.json |
COREHUB_STORAGE_ROOT |
.corehub-local/storage |
COREHUB_PUBLIC_BASE_URL |
https://coreblow.com/corehub |
COREHUB_AUDIT_RETENTION_DAYS |
365 |
This lets the upload, submit, review, and projected Registry API v1 flow run over HTTP without a test harness while still keeping production database persistence out of scope.
Phase 26 adds an end-to-end smoke script for the local server:
npm run smoke:local-publishThe smoke starts a local server on an ephemeral port, logs in with local test credentials, requests and verifies an upload slot, submits the package, approves the moderation review, and checks the projected Registry API v1 package entry.
For the manual command sequence, see docs/local-publish-runbook.md.