diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml new file mode 100644 index 0000000..3136c13 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -0,0 +1,70 @@ +name: Bug report +description: Report reproducible incorrect behavior. +title: "[Bug]: " +labels: + - bug +body: + - type: markdown + attributes: + value: | + Do not report security vulnerabilities here. Read the [security policy](https://github.com/plannotator/artifact-server/blob/main/SECURITY.md). + - type: input + id: version + attributes: + label: Version + description: Give the release version, commit SHA, or container digest. + placeholder: v0.1.0 + validations: + required: true + - type: dropdown + id: deployment + attributes: + label: Deployment mode + options: + - Local source checkout + - Local release package + - Docker Compose + - Kubernetes with Helm + - Cloudflare + - AWS + - Google Cloud + - Other + validations: + required: true + - type: textarea + id: behavior + attributes: + label: What happened? + description: Describe the incorrect behavior and its effect. + validations: + required: true + - type: textarea + id: reproduction + attributes: + label: Reproduction steps + description: Give the smallest sequence that reproduces the bug. + placeholder: | + 1. Start Artifact Server with ... + 2. Open ... + 3. Select ... + validations: + required: true + - type: textarea + id: expected + attributes: + label: Expected behavior + description: Describe the result that you expected. + validations: + required: true + - type: textarea + id: evidence + attributes: + label: Logs or screenshots + description: Remove tokens, credentials, private artifact contents, and personal data. + - type: textarea + id: environment + attributes: + label: Environment + description: Give the operating system, Node.js version, browser, and storage providers that apply. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..b1520db --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Documentation + url: https://artifactserver.com/docs/ + about: Read the installation, deployment, MCP, agent, and operator guides. + - name: Security vulnerability + url: https://github.com/plannotator/artifact-server/blob/main/SECURITY.md + about: Read the private reporting instructions. Do not open a public issue. diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml new file mode 100644 index 0000000..bdf9c2b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature.yml @@ -0,0 +1,46 @@ +name: Feature request +description: Propose a change to an Artifact Server workflow. +title: "[Feature]: " +labels: + - enhancement +body: + - type: textarea + id: problem + attributes: + label: User problem + description: Describe the task that is difficult or impossible now. + validations: + required: true + - type: textarea + id: behavior + attributes: + label: Proposed behavior + description: Describe what the user does and what Artifact Server returns. + validations: + required: true + - type: dropdown + id: scope + attributes: + label: Primary area + options: + - Review application + - CLI + - MCP + - Agent integration + - Local deployment + - Team deployment + - Storage or versioning + - Documentation + - Other + validations: + required: true + - type: textarea + id: alternatives + attributes: + label: Current workaround + description: Describe how you complete the task now, if a workaround exists. + - type: textarea + id: constraints + attributes: + label: Constraints or examples + description: Add examples, deployment limits, or compatibility requirements that affect the request. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..2651b6f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,60 @@ +# Contributing to Artifact Server + +Artifact Server accepts bug fixes, documentation corrections, tests, and focused feature changes. + +Do not use a public issue for a suspected security vulnerability. Read the [security policy](./SECURITY.md) for private reporting instructions. + +## Before you start + +Search the [open issues](https://github.com/plannotator/artifact-server/issues) before you start work. + +Open an issue before a large feature or architecture change. Describe the user problem, the proposed behavior, and the affected deployment modes. + +Small bug fixes and documentation corrections do not require an issue. + +## Development setup + +Install Node.js 24.12 or newer and pnpm 10.34.3. + +```sh +git clone https://github.com/plannotator/artifact-server.git +cd artifact-server +pnpm install +pnpm dev +``` + +The development server prints the local review URL. + +## Make a change + +Read [`AGENTS.md`](./AGENTS.md) before you change product code. The file defines the engineering and test rules for this repository. + +Build toward the contracts in [`project/spec/conformance.yml`](./project/spec/conformance.yml). Add tests for observable behavior and failure recovery. + +Use a requirement ID in each conformance test name. For example, use `ART-004-B` for a test that proves that requirement. + +Do not weaken TypeScript, Oxlint, or anti-slop rules. Do not use module mocks. + +## Verify the change + +Run focused tests while you work. Before you mark a pull request ready, run the complete gate: + +```sh +pnpm verify:iteration +``` + +This command requires Docker. Report each test that you cannot run and explain why. + +## Open a pull request + +Keep each pull request focused on one change. Include: + +- the user-visible behavior +- the affected requirement IDs +- the tests that you ran +- deployment or migration effects +- screenshots for interface changes + +Update the documentation when the behavior or operator procedure changes. + +The required GitHub checks must pass before merge. diff --git a/README.md b/README.md index 3b84431..a96e553 100644 --- a/README.md +++ b/README.md @@ -137,7 +137,7 @@ pnpm install pnpm dev ``` -Open the printed URL. Public package download and verification commands will be added on release day. See [Get started locally](https://artifactserver.com/docs/get-started/) for the current source-development path. +Open the printed URL. You can also download the portable Node.js package from the [latest GitHub release](https://github.com/plannotator/artifact-server/releases/latest). See [Get started locally](https://artifactserver.com/docs/get-started/) for package verification and startup instructions. ## Usage diff --git a/apps/site/src/content/docs/docs/deploy/index.mdx b/apps/site/src/content/docs/docs/deploy/index.mdx index 9f884d3..3f97ee4 100644 --- a/apps/site/src/content/docs/docs/deploy/index.mdx +++ b/apps/site/src/content/docs/docs/deploy/index.mdx @@ -21,7 +21,7 @@ The AWS private-ingress variant has not passed its live lifecycle gate. The Goog Use the Kubernetes guide for EKS, GKE, or AKS. Artifact Server does not provide a separate Azure installer. ## Meet the remote deployment requirements diff --git a/apps/site/src/content/docs/docs/get-started.mdx b/apps/site/src/content/docs/docs/get-started.mdx index c564e84..1d2afec 100644 --- a/apps/site/src/content/docs/docs/get-started.mdx +++ b/apps/site/src/content/docs/docs/get-started.mdx @@ -5,9 +5,34 @@ description: Run Artifact Server on a laptop and publish a first immutable artif The local target runs directly on the host with SQLite, local blob storage, and loopback-only content origins. The loopback application gives the local owner browser access without a sign-in form. The source installation requires Node.js 24.12 or newer and pnpm 10.34.3. - +## Run the packaged release + +Artifact Server `v0.1.0` includes a portable Node.js package. It requires Node.js 24.12 or newer. + + + + Download these files from the [`v0.1.0` GitHub release](https://github.com/plannotator/artifact-server/releases/tag/v0.1.0): + + - `artifact-server-0.1.0-node.tar.gz` + - `artifact-server-0.1.0-node.tar.gz.manifest.json` + + Run this command in the download directory: + + ```sh + node -e 'const crypto = require("node:crypto"); const fs = require("node:fs"); const archive = process.argv[1]; const manifest = JSON.parse(fs.readFileSync(process.argv[2], "utf8")); const actual = crypto.createHash("sha256").update(fs.readFileSync(archive)).digest("hex"); if (actual !== manifest.sha256) throw new Error("Archive checksum mismatch"); console.log(actual);' artifact-server-0.1.0-node.tar.gz artifact-server-0.1.0-node.tar.gz.manifest.json + ``` + + For provenance verification, use the [supply-chain guide](/docs/security/). + + + ```sh + tar -xzf artifact-server-0.1.0-node.tar.gz + ./artifactserver/bin/artifactserver open + ``` + + Open the printed URL. The application stores its data in `.artifact-server` by default. + + ## Run from source diff --git a/apps/site/src/content/docs/docs/index.mdx b/apps/site/src/content/docs/docs/index.mdx index 37465ab..e365098 100644 --- a/apps/site/src/content/docs/docs/index.mdx +++ b/apps/site/src/content/docs/docs/index.mdx @@ -42,7 +42,7 @@ Artifact Server stores finished browser files as immutable versions and serves e [Choose a deployment →](/docs/deploy/) - Read how CI protects source changes and what evidence each package contains. Learn which public verification assets do not exist yet. + Read how CI protects source changes and how to verify release checksums, attestations, and software bills of materials. [Read the security evidence →](/docs/security/) @@ -60,7 +60,7 @@ Artifact Server installation One installation represents one person, team, or company. A fresh installation creates a default project. Stable artifact links resolve to the current version. Exact version links never move. ## License diff --git a/apps/site/src/content/docs/docs/security.mdx b/apps/site/src/content/docs/docs/security.mdx index 140c2d6..6b7d432 100644 --- a/apps/site/src/content/docs/docs/security.mdx +++ b/apps/site/src/content/docs/docs/security.mdx @@ -98,9 +98,28 @@ A matching checksum proves that the archive matches its manifest. Until the mani ## Public release verification -No tagged public Artifact Server release exists. The release workflow passed private qualification. No public archive or image is available for external verification. +Each [GitHub release](https://github.com/plannotator/artifact-server/releases) includes package manifests, SPDX software bills of materials, and `SHA256SUMS`. Download all release assets before you verify them. -The team will add release commands after the public assets exist. These commands will download checksums and verify GitHub attestations and the immutable GHCR image. Until then, source-build evidence is the available verification boundary. +On Linux, run: + +```sh +sha256sum --check --strict SHA256SUMS +``` + +On macOS, run: + +```sh +shasum --algorithm 256 --check SHA256SUMS +``` + +GitHub also records build provenance and SBOM attestations for the downloadable files and the container image. Use GitHub CLI to verify a downloaded file: + +```sh +gh attestation verify artifact-server-0.1.0-node.tar.gz \ + --repo plannotator/artifact-server +``` + +The release asset named `image-reference.txt` contains the immutable GHCR image reference. Use that digest instead of a mutable tag in production. ## Reporting and product boundaries diff --git a/apps/web/src/review/review.css b/apps/web/src/review/review.css index 19a8eeb..9441c24 100644 --- a/apps/web/src/review/review.css +++ b/apps/web/src/review/review.css @@ -1680,7 +1680,7 @@ select:focus-visible { .as-share-link h3, .as-share-agent h3 { - color: var(--as-subtle); + color: color-mix(in oklab, var(--as-subtle) 80%, var(--as-text)); font-size: 0.65rem; font-weight: 600; letter-spacing: 0.08em; diff --git a/package.json b/package.json index 258aa57..13928bb 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,8 @@ "@prisma/dev>hono": "4.13.1", "@prisma/dev>valibot": "1.4.2", "chevrotain@10.5.0>lodash": "4.18.0", + "fast-uri": "3.1.6", + "qs": "6.16.0", "gaxios>uuid": "11.1.1" } }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a97f922..b667d83 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,8 @@ overrides: '@prisma/dev>hono': 4.13.1 '@prisma/dev>valibot': 1.4.2 chevrotain@10.5.0>lodash: 4.18.0 + fast-uri: 3.1.6 + qs: 6.16.0 gaxios>uuid: 11.1.1 importers: @@ -5095,8 +5097,8 @@ packages: fast-string-width@3.0.2: resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} - fast-uri@3.1.5: - resolution: {integrity: sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==} + fast-uri@3.1.6: + resolution: {integrity: sha512-7Ical1vFEMr0onbVzEDIreM22I4khW+fzyQPwvAFWBp1iwdshSZRsL4jjRvPG9JP1uiqMHRto+YU6R2/CzDz5Q==} fast-wrap-ansi@0.2.2: resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} @@ -6946,8 +6948,8 @@ packages: pure-rand@8.4.2: resolution: {integrity: sha512-vvuOGgcuPJAirlHvuQw1TrOiw7ptaIXXmIbNuiNOY6lNGJJH49PQ1Kj4nd783nPdQhQdicgOjVI2yI/9BD6/Ng==} - qs@6.15.3: - resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==} + qs@6.16.0: + resolution: {integrity: sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==} engines: {node: '>=0.6'} queue-microtask@1.2.3: @@ -12204,7 +12206,7 @@ snapshots: ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.1.5 + fast-uri: 3.1.6 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 @@ -12468,7 +12470,7 @@ snapshots: http-errors: 2.0.1 iconv-lite: 0.7.3 on-finished: 2.4.1 - qs: 6.15.3 + qs: 6.16.0 raw-body: 3.0.2 type-is: 2.1.0 transitivePeerDependencies: @@ -13345,7 +13347,7 @@ snapshots: once: 1.4.0 parseurl: 1.3.3 proxy-addr: 2.0.7 - qs: 6.15.3 + qs: 6.16.0 range-parser: 1.3.0 router: 2.2.0 send: 1.2.1 @@ -13378,7 +13380,7 @@ snapshots: dependencies: fast-string-truncated-width: 3.0.3 - fast-uri@3.1.5: {} + fast-uri@3.1.6: {} fast-wrap-ansi@0.2.2: dependencies: @@ -15560,7 +15562,7 @@ snapshots: pure-rand@8.4.2: {} - qs@6.15.3: + qs@6.16.0: dependencies: es-define-property: 1.0.1 side-channel: 1.1.1