Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
#!/bin/sh
unset $(git rev-parse --local-env-vars)
exec npm run check
1 change: 1 addition & 0 deletions .githooks/pre-push
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
#!/bin/sh
unset $(git rev-parse --local-env-vars)
exec npm run check
12 changes: 10 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
Expand All @@ -47,12 +48,15 @@ jobs:
- name: Verify effective IDE project declarations
if: runner.os == 'Windows'
run: node tooling/project.ts licence-evaluated
- name: Retain project licence declarations
- name: Retain source licence and provenance evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: licence-evidence-${{ matrix.os }}-${{ github.run_id }}-${{ github.run_attempt }}
path: artifacts/evidence/licence-*.json
path: |
artifacts/evidence/licence-*.json
artifacts/evidence/source-provenance.json
artifacts/evidence/browser-graph.json
if-no-files-found: error
retention-days: 30

Expand Down Expand Up @@ -88,6 +92,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
with:
Expand All @@ -107,6 +112,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 0
persist-credentials: false
- uses: github/codeql-action/init@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4
with:
Expand All @@ -126,6 +132,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
Expand Down Expand Up @@ -192,6 +199,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
Expand Down
17 changes: 17 additions & 0 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Exact public-source checksum false positives, independently verified against upstream bytes.
[extend]
useDefault = true

[[allowlists]]
description = "Reviewed public source hashes in the immutable browser resource profile"
condition = "AND"
targetRules = ["generic-api-key"]
regexTarget = "line"
paths = ['''^eng/provenance/profiles/browser-resources-r1\.json$''']
regexes = [
'''^\s*"(?:apps/site/)?node_modules/@bufbuild/protobuf/dist/esm/wkt/gen/google/protobuf/api_pb\.js": "73e489001027c703bc0224ae73f78ecefe028e88284bd06952e8603c3d81472c",?$''',
'''^\s*"node_modules/@connectrpc/connect-web/dist/esm/assert-fetch-api\.js": "bd56033776818aaa82959c12561dd084d3a730180e6e8f1e681f5d3d439b6474",?$''',
'''^\s*"packages/protobuf/src/wkt/gen/google/protobuf/api_pb\.ts": "(?:538052ccd9a02c464702000dfc92a5e7cc01b7b5f55970b14af39662c7b46ae5|440d9371d9b04a8025e6f89d0041c2a54c7c926abedfbd24cef1432ec3fc38a4)",?$''',
'''^\s*"packages/connect-web/src/assert-fetch-api\.ts": "b577e990dcf088f942a1dcf66405aab52c7d6f72bed2757c64e213e32ce91dac",?$''',
'''^\s*"packages/shared/ReactFlightPropertyAccess\.js": "b80258eb57aa5de9d4386788424c10b259b87b76f84498605bf10f0b0dd7c793",?$''',
]
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ Workers Static Assets supports this static React build directly. Frameworks that

The build and CI enforce the [project licence declarations](docs/licence-boundary.md)
across every npm workspace and the JavaScript IDE adapter.
They also enforce [source and actual browser artifact provenance](docs/provenance.md),
including complete legal notices, immutable reuse records and the emitted browser SBOM.

Read [development](docs/development.md), [contributing](CONTRIBUTING.md), [security](SECURITY.md), [validation](docs/validation.md), and the [bootstrap plan](docs/bootstrap-plan.md).

Expand Down
6 changes: 5 additions & 1 deletion THIRD_PARTY_NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ First-party Web code retains this repository's **AGPL-3.0-only** license. Depend
- `@arcforges/proto` and `@arcforges/api-client` 1.0.0-ci.25.1 are published Apache-2.0 packages from [ArcForges Contracts](https://github.com/ArcForges/Contracts). Their original LICENSE, NOTICE, source manifest and SBOM are copied into the candidate.
- The protobuf runtime is Apache-2.0 AND BSD-3-Clause. Connect runtimes are Apache-2.0. The build preserves the Buf/Connect copyright headers, Apache license and complete Google varint BSD notice; see [supplementary upstream licenses](third-party/README.md).
- React, React DOM, Scheduler, React Router and related runtime dependencies carry their upstream license texts. Those texts and the other production dependency notices are collected from the installed lockfile closure into public `/third-party-notices.txt`.
- Development/build dependencies are recorded in the full candidate CycloneDX SBOM; a separate runtime dependency SBOM describes the production closure. They may list code removed by tree-shaking or used only during prerendering.
- Development/build dependencies and platform alternatives are recorded in the full lockfile CycloneDX SBOM. The separate browser SBOM describes actual emitted modules, stylesheet/helper origins and their relationships; parsed-only and prerender-only implementations are excluded from that browser closure.

No external fonts, photographs, GPL media library source or reference-product assets are copied into this Hello site. The simple mark and visual elements are first-party SVG/CSS.

## Browser packaging provenance

The generated public notices preserve full production dependency terms and the additional Vite, Rolldown (including its referenced MIT companions), Tailwind, turbo-stream/devalue and original Google protobuf terms. Immutable source/artifact records and `eng/provenance/NOTICE.txt` document these obligations. The source summary does not replace full legal text. See [the provenance process](docs/provenance.md) and [retained documents](third-party/README.md).
3 changes: 2 additions & 1 deletion apps/site/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
import { reactRouter } from "@react-router/dev/vite";
import tailwindcss from "@tailwindcss/vite";
import { defineConfig } from "vite";
import { observeBrowser } from "../../tooling/browser-provenance.ts";

export default defineConfig({
plugins: [tailwindcss(), reactRouter()],
plugins: [tailwindcss(), reactRouter(), observeBrowser()],
build: { sourcemap: false },
});
4 changes: 4 additions & 0 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,7 @@ Browser reports, traces for failures and responsive screenshots are under `playw
Local Wrangler persistence is explicitly placed at the repository's ignored `.wrangler/state`, outside the immutable candidate. Verification runs again after browser tests to catch any unexpected tool writes into that artifact.

`manifest.json` records a full source SHA, version, dirty flag and hash of every other candidate file. Local modified builds are useful for testing but rejected by automatic deployment. `__build.json` exposes only the non-sensitive source/version identity. A successful build is not evidence of a real Cloudflare deployment or working C# business API.

## Provenance changes

Follow [the provenance process](provenance.md) before introducing reused or generated material. `npm run check` includes `npm run test:provenance`, which first builds an actual candidate and then runs source-policy and resealed-candidate failure scenarios. `npm run verify:candidate` validates the independent browser resource profile and complete legal/SBOM closure as well as the outer manifest.
33 changes: 33 additions & 0 deletions docs/provenance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Reuse and artifact provenance

Design's [current-repository and packaging profiles](https://github.com/ArcForges/ArcForges-Design/blob/5322d698a1b650a52a5a139d986dd85b00b48581/docs/assurance/reference-coverage-and-provenance.md#31-current-repository-implementation-profile) govern this owner. The current Web repository is the audit subject. Retired initialization repositories are not producers or build inputs.

## Before accepting material

The Licensing and Provenance Owner, including a maintainer-authorized implementation reviewer, inspects the particular source, tests, assets, wrappers, generated inputs and legal documents. Record the actual reviewer, date and compatibility rationale. The Architecture Owner resolves ownership/boundary questions; the Product Owner decides product changes. The five-row decision table in `eng/policy/reuse-policy.json` is closed. An unknown expression or origin fails; a package-root label alone does not settle a file's licence. Unlicense is explicitly classified after reviewing its complete commercial-copying permission. This does not add a policy exception.

Copy `eng/provenance/template.json` into a new `eng/provenance/records/<material>-r1.json`. Complete the ten evidence subjects: canonical repository, immutable commit, explicit paths, file-level licence evidence, attribution, targets, disposition, verification oracle, distributed notices and lifetime. The template is not approved material. Complete and review the record **before** introducing the reused material. Generated records identify every generator and input, their respective licences, the command and resulting licence position. Temporary reuse also names an owner and observable removal trigger.

Bind each target in `eng/provenance/files.json` to its record and SHA-256. Text hashes explicitly normalize CRLF to LF; binary hashes use raw bytes. Account for all tracked files, including tracked ignored files, and non-ignored new files. Authored classifications require contribution review, including reused material inserted into an existing file. Inventory automation cannot prove authorship.

Used records are append-only. Do not edit, reformat or remove them. A changed input, target, intent or obligation needs a new revision citing `supersedes`; update the active binding and retain history. Initial reconciliation states the inspected owner commit and does not claim that records existed before historical copying. The canonical AGPL record identifies a byte oracle, not an invented historical download origin. Legal-document records admit full legal text only, never the implementation governed by it.

`eng/provenance/NOTICE.txt` is a deterministic active-record summary. Regenerate it after reviewing inventory changes with the exported `auditProvenance(root, { writeNotice: true })` operation, then run normal checks. It supplements full legal texts and existing dependency notices. Source tooling copied from Cloud stays AGPL, has exact source/test attribution and creates no sibling-source dependency.

## Actual browser candidate

The immutable browser profile binds exact npm integrity, upstream commits and source/archive evidence, installed input hashes, the actual parsed and emitted graph, and every browser resource. Vite observes the actual client compilation without changing output. Generated Vite/Rolldown helpers, Tailwind styles, Router's embedded turbo-stream and the original protobuf schemas are explicit origins. The complete original MIT companions and Google BSD terms supplement the existing notices. Parsed-only modules and prerender-only isbot are distinguished from emitted implementation.

The initial independent oracle used two actual builds at different source identities. All 18 browser files matched after allowing only the exact source revision, asset basenames and the Router manifest fingerprint derived from its entry/routes. New or changed executable bodies, resources, graph members or legal bytes fail even when an outer manifest and receipt are recalculated. Dependency or application changes affecting those inputs require a newly reviewed profile and superseding artifact record. Never regenerate an oracle merely to make a failure pass.

The build SBOM uses the complete lockfile, including platform alternatives, and has a stable workspace name. The separate browser SBOM records actual emitted origins and module-derived relationships, including embedded origins and generated helpers. The initial `npm sbom --omit=dev` output omitted several emitted React-family packages; it is not the browser closure oracle. Build-only tools do not become runtime components merely because they generate code.

The candidate carries its active records, reviewed profile, observed graph and source-bound receipt under private `provenance/`. The receipt contains every actual candidate member hash. Full licences, third-party notices and the provenance summary are also public assets. The same gate checks exact Contracts package legal/source/SBOM bytes, both SBOMs, derived CSP/security/cache headers, deployment configuration, complete file membership and source/version identity before tests, deployment and public consumption. Source maps, SSR implementation, dependencies and private evidence remain outside public assets.

`npm run check` runs source enforcement, unit checks and provenance failure scenarios against a real built candidate on Windows and Linux. CI fetches full trusted history: PR base SHA, push `before` SHA, or the current committed baseline for scheduled/manual runs. Missing history fails. Commit/push hooks clear inherited Git repository-selection variables before running the same checks. CI retains source and actual graph evidence; the deploy job verifies the downloaded candidate without rebuilding it.

## Conflicting contributions

Register the affected material and evidence at `eng/provenance/conflicts/<id>.json` with `schemaVersion`, `id`, `material`, `evidence`, `boundary`, `owner`, `requiredDecision`, `status` and `resolution`. An unresolved conflict blocks acceptance and distribution. Return it to the accountable owner; resolve it through the formal decision and a new admissible record, or remove the affected material. No silent licence exception, boundary change or dropped product is permitted. An existing release conflict also invokes the owning release-remediation process.

Browser tests exercise the CF Web application in Chromium, Firefox and WebKit. Wide and narrow viewport screenshots are browser evidence. They do not establish Avalonia desktop or Kotlin/Compose Android behaviour. Native clients retain their separate implementation and verification boundaries.
4 changes: 2 additions & 2 deletions docs/validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Evidence is recorded separately for source checks, local production assets, host

- Windows pinned toolchain: exact dependency restore, policy, formatting, Biome, strict TypeScript and eight unit/component/SDK/delivery tests have passed.
- A static candidate with source identity, file hashes, CSP, licenses, Contracts provenance and SBOMs has been built and verified locally.
- Twelve production-browser tests passed across Chromium, Firefox and WebKit against local Wrangler. They cover hydration under the generated CSP, greeting/validation, no transmitted name, no-JavaScript content/navigation, axe WCAG checks, narrow layout, cache/security headers and real 404s. Desktop and mobile screenshots were visually inspected.
- Twelve production-browser tests passed across Chromium, Firefox and WebKit against local Wrangler. They cover hydration under the generated CSP, greeting/validation, no transmitted name, no-JavaScript content/navigation, axe WCAG checks, narrow layout, cache/security headers and real 404s. Wide and narrow browser viewport screenshots were visually inspected; these are not native desktop or Android application tests.
- npm audit reported zero known vulnerabilities. The SHA-verified actionlint 1.7.12 executable accepted the workflow.
- `dotnet build win.slnx --no-restore` accepted the optional solution with workload resolution disabled; it is not evidence of interactive Visual Studio startup or a separate .NET build.
- GitHub PR checks will provide separate hosted Linux/Windows, CodeQL, dependency-review, secret-scan and browser evidence. Their result is reported on the PR.
Expand All @@ -28,7 +28,7 @@ The custom-domain change and its bounded propagation correction are now deployed
## Cloud Hello preparation: local evidence

- Source checks passed with twelve unit/component/SDK/delivery tests after rebasing onto the verified custom-domain main commit.
- The candidate build and all eighteen Chromium/Firefox/WebKit checks passed, followed by candidate hash/file-set verification. Desktop and narrow-screen connection pages were visually inspected.
- The candidate build and all eighteen Chromium/Firefox/WebKit checks passed, followed by candidate hash/file-set verification. Wide and narrow browser viewport connection pages were visually inspected.
- Candidate tests confirm GET 404 and POST 405 before a Cloud API exists, explicitly mocked unavailable/success responses through the published binary client, and no automatic requests or retries. These do not validate a C# container.
- Listing the live suite confirms fifteen static/idle-page tests and excludes the three browser wire-fixture cases. This feature has not been deployed; its public API and Native AOT evidence remain pending Cloud implementation.

Expand Down
45 changes: 45 additions & 0 deletions eng/policy/reuse-policy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"schemaVersion": 1,
"repository": "Web",
"licenceBoundary": "AGPL",
"authority": {
"repository": "https://github.com/ArcForges/ArcForges-Design",
"commit": "5322d698a1b650a52a5a139d986dd85b00b48581",
"path": "docs/assurance/reference-coverage-and-provenance.md"
},
"decisions": {
"permissive": {
"AGPL": "audit",
"Apache": "audit"
},
"agpl-compatible": {
"AGPL": "exact-review",
"Apache": "prohibited"
},
"gpl-only": {
"AGPL": "prohibited",
"Apache": "prohibited"
},
"unclear": {
"AGPL": "prohibited",
"Apache": "prohibited"
},
"incompatible": {
"AGPL": "prohibited",
"Apache": "prohibited"
}
},
"licences": {
"Apache-2.0": "permissive",
"MIT": "permissive",
"BSD-2-Clause": "permissive",
"BSD-3-Clause": "permissive",
"ISC": "permissive",
"AGPL-3.0-only": "agpl-compatible",
"GPL-2.0-only": "gpl-only",
"GPL-3.0-only": "gpl-only",
"NOASSERTION": "unclear",
"EPL-1.0": "incompatible",
"Unlicense": "permissive"
}
}
Loading
Loading