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
91 changes: 47 additions & 44 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -1,48 +1,51 @@
name: Publish apply surface

on:
push:
branches: [ main ]
workflow_dispatch:

push:
branches: [ main ]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: true

contents: read
pages: write
id-token: write
jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v4
- uses: actions/configure-pages@v5

- name: Prepare artifact
shell: bash
run: |
set -euo pipefail
rm -rf dist
mkdir -p dist/submit dist/task dist/confirm
cp CNAME dist/CNAME
cp public/index.html dist/index.html
cp public/404.html dist/404.html
cp public/submit/index.html dist/submit/index.html
cp public/task/index.html dist/task/index.html
cp public/confirm/index.html dist/confirm/index.html
cp -R surface-system dist/surface-system
grep -Fx "apply.verifrax.net" dist/CNAME
test -f dist/surface-system/shell/base.css

- uses: actions/upload-pages-artifact@v3
with:
path: dist

- id: deployment
uses: actions/deploy-pages@v4
contract:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "22"
- run: npm test
- run: npm run verify
deploy-static-fallback:
needs: contract
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v4
- uses: actions/configure-pages@v5
- name: Prepare static artifact
shell: bash
run: |
set -euo pipefail
rm -rf dist
mkdir -p dist
cp -R public/. dist/
cp CNAME dist/CNAME
grep -Fx "apply.verifrax.net" dist/CNAME
test -f dist/index.html
test -f dist/task/index.html
test -f dist/submit/index.html
test -f dist/confirm/index.html
test -f dist/status/index.html
test -f dist/privacy/index.html
test -f dist/admin/index.html
test -f dist/tasks/protocol-review.json
test -f dist/schemas/submission.schema.json
- uses: actions/upload-pages-artifact@v3
with:
path: dist
- id: deployment
uses: actions/deploy-pages@v4
5 changes: 3 additions & 2 deletions 404.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>VERIFRAX Apply</title>
<meta name="description" content="Intake surface for the VERIFRAX public perimeter. This surface accepts intake only. It does not publish proof, determine verification truth, issue authority, or execute governed actions.">
<meta name="description" content="Terminal intake control plane for VERIFRAX. This host converts untrusted human intent into structured private review signal only. It does not publish proof, verify truth, issue authority, execute governed actions, recognize terminal truth, or assign recourse.">
<link rel="canonical" href="https://apply.verifrax.net/">
<link rel="stylesheet" href="assets/surface.css">
</head>
<body>
<main class="wrap">
<div class="kicker">VERIFRAX / apply</div>
<h1>404 — VERIFRAX Apply</h1>
<p class="lead">Intake surface for the VERIFRAX public perimeter. This surface accepts intake only. It does not publish proof, determine verification truth, issue authority, or execute governed actions.</p>
<p class="lead">Terminal intake control plane for VERIFRAX. This host converts untrusted human intent into structured private review signal only. It does not publish proof, verify truth, issue authority, execute governed actions, recognize terminal truth, or assign recourse.</p>
<p class="copy">Bounded public tool surface inside the VERIFRAX perimeter.</p>
<div class="rule"></div>

Expand All @@ -28,6 +28,7 @@ <h2>System map</h2>
<li class="row"><span class="label">Runtime</span><span class="value"><a href="https://corpiform.verifrax.net">corpiform.verifrax.net</a></span></li>
<li class="row"><span class="label">Execution</span><span class="value"><a href="https://api.verifrax.net">api.verifrax.net</a></span></li>
<li class="row"><span class="label">Status</span><span class="value"><a href="https://status.verifrax.net">status.verifrax.net</a></span></li>
<li class="row"><span class="label">Archive</span><span class="value"><a href="https://sigillarium.verifrax.net">sigillarium.verifrax.net</a></span></li>
</ul>
</article>

Expand Down
177 changes: 28 additions & 149 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,169 +1,48 @@
# APPLY

* License: GNU Affero General Public License v3.0
APPLY is the VERIFRAX terminal intake control plane.

APPLY is the Verifrax intake boundary: the public surface that accepts structured intake into the Verifrax system without becoming authored protocol source, authority issuance, governed execution, public verification, proof publication, or archive/reference.
`APPLY = intake(filter(humans)) -> structured_signal`

## Proof artifacts
APPLY accepts structured intake, rejects incomplete intake, normalizes applicant signal, scores reviewability, issues intake receipts, routes records into a private queue, exposes protected reviewer workflow, and emits review state.

This repository is part of the VERIFRAX proof perimeter.
APPLY does not decide truth.

- **ARTIFACT-0006**
- **ARTIFACT-0005**
- **ARTIFACT-0004**
- **ARTIFACT-0003**
- **ARTIFACT-0002**
- **ARTIFACT-0001**
APPLY may not define law, accept canonical state, issue authority, execute governed actions, verify artifacts, publish proof, archive evidence, recognize terminal truth, assign terminal recourse, or publish applicant PII.

**Canonical public proof surface:** https://proof.verifrax.net
**Canonical proof publication repository:** https://github.com/Verifrax/proof
**Canonical evidence root:** https://github.com/Verifrax/VERIFRAX
## Live host

## Terminal planes
https://apply.verifrax.net

- **[ANAGNORIUM](https://github.com/Verifrax/ANAGNORIUM)** — terminal recognition
- **[REGRESSORIUM](https://github.com/Verifrax/REGRESSORIUM)** — terminal recourse
## Required routes

## Status
Public: `/`, `/task`, `/submit`, `/confirm`, `/status`, `/privacy`, `/admin`.

* Surface class: intake
* Repository class: intake host surface
* Public host ownership: `apply.verifrax.net`
* Host class: tool
* Role: apply
* Deploy mode: static-root
* Current repository posture: live public intake boundary
## Boundary
API: `/api/submit`, `/api/confirm`, `/api/status`, `/api/admin/submissions`, `/api/admin/submission/:id`.

This repository owns structured intake only.
## Tracks

It accepts bounded submissions into the Verifrax system.
It exposes intake-surface role truth and intake-entry behavior.
- protocol-review
- security-adversarial-review
- verifier-engineering
- surface-frontend
- enterprise-compliance
- documentation-systems

It does not author normative source material.
It does not issue authority.
It does not execute governed actions.
It does not verify published material.
It does not publish proof.
It does not serve as archive/reference.
It does not replace adjacent sovereign boundaries.
## Queue states

## What it does
`new`, `review`, `accepted`, `rejected`, `deferred`, `spam`, `quarantined`.

- accepts structured intake into the Verifrax system
- provides a bounded host surface for intake entry
- preserves a clean intake boundary for public users and system routing
- keeps intake distinct from authority, execution, verification, proof publication, and archive/reference
- anchors intake-surface role truth for adjacent repositories and hosts
## Scoring law

## What it does not do
`S = 0.5 * output_presence + 0.2 * link_quality + 0.2 * alignment + 0.1 * clarity`

- not authored protocol source; that belongs to VERIFRAX
- not authority issuance; that belongs to AUCTORISEAL
- not governed execution; that belongs to CORPIFORM
- not public verification; that belongs to VERIFRAX-verify
- not proof publication; that belongs to proof
- not archive/reference; that belongs to SIGILLARIUM
- not constitutional doctrine; that belongs to SYNTAGMARIUM
- not canonical world-state; that belongs to ORBISTIUM
- not reconciliation or repair; that belongs to CONSONORIUM
- not sovereign cognition; that belongs to TACHYRIUM
## Runtime

## Adjacent sovereign surfaces
Cloudflare Pages Functions + D1:

- `VERIFRAX` — authored protocol and evidence-root boundary
- `AUCTORISEAL` — authority issuance
- `CORPIFORM` — governed execution
- `VERIFRAX-verify` — public verification
- `proof` — proof publication
- `SIGILLARIUM` — archive/reference

VERIFRAX authors.
AUCTORISEAL issues.
CORPIFORM executes.
proof publishes.
VERIFRAX-verify verifies.
APPLY accepts intake.

That separation must remain explicit.

## Public host ownership

This repository owns the public intake host for:

* `https://apply.verifrax.net/`

That host must remain intake only.

It must not become:

* authored protocol source
* authority issuance
* governed execution
* verifier UI
* proof publication
* archive/reference
* docs mirror
* commercial landing

## Public surface

The public surface of this repository is its repository identity, README boundary, public intake host surface, and intake-facing materials carried by this repository.

Publication here is not authored source.
Publication here is not authority.
Publication here is not execution.
Publication here is not verification.
Publication here is not proof publication.
Publication here is not archive/reference.

## Package / host / repo truth

Repository truth for APPLY lives in this repository.

Host truth for this surface is `https://apply.verifrax.net/`.
Host presentation and repository truth are related but not interchangeable.
Repository boundary still controls intake role truth here.

## Intake meaning in-system

Intake in-system means the stack can point to APPLY and say that a bounded intake surface, intake-entry path, or submission-acceptance surface belongs to this boundary.

Intake here accepts.
Intake here does not author.
Intake here does not issue authority.
Intake here does not execute.
Intake here does not verify.
Intake here does not publish proof.

That does not by itself mean:

- the intake surface became authored protocol source
- the intake surface issued authority
- the intake surface executed a governed action
- the intake surface verified truth
- the intake surface published proof
- the intake surface replaced archive/reference
- the intake surface replaced the evidence-root repository

## Not this

APPLY is not authored protocol source.
APPLY is not authority issuance.
APPLY is not governed execution.
APPLY is not public verification.
APPLY is not proof publication.
APPLY is not archive/reference.

## Validation

- `surface.host.json` must continue to declare:
- repo = `apply`
- host = `https://apply.verifrax.net`
- hostClass = `tool`
- role = `apply`
- deployMode = `static-root`

## License

This repository is licensed under the GNU Affero General Public License v3.0. See `LICENSE`.
- `APPLY_DB`
- `ADMIN_TOKEN`
- `RECEIPT_HMAC_SECRET`
- `TURNSTILE_SECRET`
- `APPLY_WEBHOOK_URL`
28 changes: 28 additions & 0 deletions docs/APPLY_TERMINAL_INTAKE_CONTROL_PLANE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# APPLY Terminal Intake Control Plane

A static page saying "submit" is not intake.

Finished APPLY completes:

`visitor -> self-selection filter -> bounded task -> structured artifact -> validation -> score -> receipt -> private queue -> sixty-second decision`

No public APPLY surface may make an applicant submission appear verified, authorized, proven, recognized, or accepted as truth.

## Release gates

1. Six bounded task lanes exist.
2. Form captures required structured signal.
3. Missing artifact is rejected.
4. Missing work link is rejected.
5. Honeypot is rejected.
6. Overlong narrative is rejected.
7. Submission receives deterministic score.
8. Submission writes to private queue.
9. Receipt is generated.
10. Admin queue requires bearer token.
11. Reviewer can transition queue state.
12. Full record read is protected.
13. Public confirmation is receipt-only.
14. Status route is APPLY-only.
15. PII never enters public repository.
16. Static contract tests pass.
21 changes: 21 additions & 0 deletions docs/CLOUDFLARE_DEPLOYMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# APPLY Cloudflare Deployment

```bash
wrangler d1 create verifrax-apply
wrangler d1 migrations apply verifrax-apply
wrangler pages secret put ADMIN_TOKEN
wrangler pages secret put RECEIPT_HMAC_SECRET
````

Optional:

```bash
wrangler pages secret put TURNSTILE_SECRET
wrangler pages secret put APPLY_WEBHOOK_URL
```

Admin: `https://apply.verifrax.net/admin`

Queue: `/api/admin/submissions?state=new`

Record: `/api/admin/submission/:id`
4 changes: 4 additions & 0 deletions functions/api/admin/submission/[id].ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { json, fail } from "../../../lib/http";
import { assertAdmin } from "../../../lib/auth";
interface Env { APPLY_DB: D1Database; ADMIN_TOKEN: string; }
export const onRequestGet: PagesFunction<Env> = async ({request,env,params})=>{if(!assertAdmin(request,env))return fail("unauthorized",401);const id=Array.isArray(params.id)?params.id[0]:params.id;const row:any=await env.APPLY_DB.prepare("select * from submissions where id = ?").bind(id).first();if(!row)return fail("not_found",404);return json({ok:true,submission:{...row,score:JSON.parse(row.score_json),receipt:JSON.parse(row.receipt_json),submission:JSON.parse(row.submission_json)}})};
6 changes: 6 additions & 0 deletions functions/api/admin/submissions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { json, fail } from "../../lib/http";
import { assertAdmin } from "../../lib/auth";
import { STATES, REVIEW_REASONS } from "../../lib/validation";
interface Env { APPLY_DB: D1Database; ADMIN_TOKEN: string; }
export const onRequestGet: PagesFunction<Env> = async ({request,env})=>{if(!assertAdmin(request,env))return fail("unauthorized",401);const state=new URL(request.url).searchParams.get("state")||"new";const rows=await env.APPLY_DB.prepare("select id, created_at, updated_at, state, track, github_url, artifact_url, score_total, score_json from submissions where state = ? order by created_at desc limit 100").bind(state).all();return json({ok:true,state,submissions:rows.results})};
export const onRequestPatch: PagesFunction<Env> = async ({request,env})=>{if(!assertAdmin(request,env))return fail("unauthorized",401);const input:any=await request.json();if(!STATES.has(input.state))return fail("invalid_state",400);if(input.reason&&!REVIEW_REASONS.has(input.reason))return fail("invalid_reason",400);await env.APPLY_DB.prepare("update submissions set state = ?, updated_at = ? where id = ?").bind(input.state,new Date().toISOString(),input.id).run();await env.APPLY_DB.prepare("insert into review_decisions (id, submission_id, created_at, decision, reason, produced_something, aligned, above_baseline, review_seconds) values (?, ?, ?, ?, ?, ?, ?, ?, ?)").bind(crypto.randomUUID(),input.id,new Date().toISOString(),input.state,input.reason||null,Boolean(input.produced_something),Boolean(input.aligned),Boolean(input.above_baseline),Number(input.review_seconds||0)).run();await env.APPLY_DB.prepare("insert into submission_events (id, submission_id, created_at, from_state, to_state, actor, reason) values (?, ?, ?, ?, ?, ?, ?)").bind(crypto.randomUUID(),input.id,new Date().toISOString(),null,input.state,"admin",input.reason||"manual_review").run();return json({ok:true})};
3 changes: 3 additions & 0 deletions functions/api/confirm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { json, fail } from "../lib/http";
interface Env { APPLY_DB: D1Database; }
export const onRequestGet: PagesFunction<Env> = async ({ request, env }) => { const id=new URL(request.url).searchParams.get("id"); if(!id)return fail("missing_id",400); const row:any=await env.APPLY_DB.prepare("select receipt_json from submissions where id = ?").bind(id).first(); if(!row)return fail("not_found",404); return json({ok:true,receipt:JSON.parse(row.receipt_json)}); };
2 changes: 2 additions & 0 deletions functions/api/status.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { json } from "../lib/http";
export const onRequestGet: PagesFunction = async () => json({ok:true,role:"apply_intake_only",truth_warning:"INTAKE_ONLY_NOT_TRUTH",queue_states:["new","review","accepted","rejected","deferred","spam","quarantined"]});
Loading
Loading