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
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name: "Verify korg Gold Seal"
name: "Verify korg Certificate"
description: >-
Independently verify goldseal@v1 certificates or korg-ledger@v1 sessions in CI —
Independently verify korgcert@v1 certificates or korg-ledger@v1 sessions in CI —
hash chain, causal DAG, re-derived summary, and the Ed25519 issuer seal. Zero
trust in whoever produced the artifact; no network. Renders a rich report into
the job summary and (on pull_request) posts a sticky Gold Seal comment. Fails
the job summary and (on pull_request) posts a sticky Certificate comment. Fails
the job on any tampered or unverifiable file.
author: "Korg ecosystem maintainers"
branding:
Expand All @@ -19,7 +19,7 @@ inputs:
required: false
default: ""
comment:
description: "Post/update a sticky Gold Seal comment on the PR (pull_request events). 'true'/'false'."
description: "Post/update a sticky Certificate comment on the PR (pull_request events). 'true'/'false'."
required: false
default: "true"
github-token:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Verify korg Gold Seals / ledgers, render a rich Markdown report into the job
// Verify korg Certificates / ledgers, render a rich Markdown report into the job
// summary, and (on a pull_request) upsert a single sticky PR comment. Reuses the
// repo's conformance-pinned verify.mjs — zero extra deps. Exit 0 iff all valid.
import { appendFileSync, readFileSync } from "node:fs";
Expand Down Expand Up @@ -49,7 +49,7 @@ for (const f of files) {
const allValid = results.every((r) => r.verdict && r.verdict.valid);

const L = [];
L.push(allValid ? "## 🛡️ ✅ Gold Seal verified" : "## 🛡️ ❌ Gold Seal verification FAILED");
L.push(allValid ? "## 🛡️ ✅ Certificate verified" : "## 🛡️ ❌ Certificate verification FAILED");
L.push("");
L.push("_Independently verified — zero trust in the tool that produced it._");
L.push("");
Expand All @@ -64,7 +64,7 @@ for (const r of results) {
const e = r.env || {};
L.push(`### ${v.valid ? "✅" : "❌"} \`${r.f}\` — ${v.kind} ${v.valid ? "VALID" : "INVALID"}`);
L.push("");
if (v.kind === "goldseal") {
if (v.kind === "korgcert") {
const s = e.summary || {};
// Every field below is seal-derived (untrusted) → esc() before interpolation,
// and NOT wrapped in backticks (esc neutralizes them, which would break a span).
Expand Down Expand Up @@ -143,10 +143,10 @@ if (wantComment && token && repo && pr) {
headers: h,
body: JSON.stringify({ body }),
});
console.log(`korg: updated sticky Gold Seal comment ${existing.id} on PR #${pr}`);
console.log(`korg: updated sticky Certificate comment ${existing.id} on PR #${pr}`);
} else {
await fetch(issueComments, { method: "POST", headers: h, body: JSON.stringify({ body }) });
console.log(`korg: posted Gold Seal comment on PR #${pr}`);
console.log(`korg: posted Certificate comment on PR #${pr}`);
}
} catch (e) {
console.log(`::warning::korg could not upsert the PR comment: ${e.message}`);
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
push:
branches: [main, develop, "feat/**"]
pull_request:
# Run on every PR regardless of base, so stacked PRs (e.g. goldseal → phase2)
# Run on every PR regardless of base, so stacked PRs (e.g. korgcert → phase2)
# get the full cargo + pytest + cross-language conformance gate too.

env:
Expand Down Expand Up @@ -53,7 +53,7 @@ jobs:
run: cargo build --workspace --verbose

# --workspace tests every member (root korg package + korg-verify/-ledger
# goldseal+fuzz suites + korg-registry journal/rewind, etc.). The root being
# korgcert+fuzz suites + korg-registry journal/rewind, etc.). The root being
# both a [workspace] and a [package] means a bare `cargo test` would only run
# the root package — verified `cargo test --workspace` is green.
- name: Run tests (workspace)
Expand Down Expand Up @@ -122,7 +122,7 @@ jobs:
- name: Install test deps
# pytest + the optional-extra deps so the FULL suite runs in CI rather
# than skipping: hypothesis (property tests) and cryptography (Ed25519
# signing / goldseal mint+verify / korg-seal).
# signing / korgcert mint+verify / korg-seal).
run: python3 -m pip install --quiet pytest hypothesis cryptography

- name: Producer + capture + setup + reader test suites
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
name: Gold Seal demo — mint → verify in CI
name: Certificate demo — mint → verify in CI

# Dogfoods the whole loop in GitHub Actions: build a session ledger, mint a
# goldseal@v1 with korg-seal, verify it with the independent verifier (pinned to
# korgcert@v1 with korg-seal, verify it with the independent verifier (pinned to
# the issuer), and prove a tampered copy is rejected. This is what "verified
# agent work in CI" looks like.
on:
workflow_dispatch:
# On PRs: mint + verify and post a sticky Gold Seal check comment (the demo).
# On PRs: mint + verify and post a sticky Certificate check comment (the demo).
pull_request:
paths:
- "adapters/korg-seal/**"
- "adapters/korg-ledger-py/**"
- "spec/korg-ledger-v1/**"
- ".github/actions/verify-goldseal/**"
- ".github/workflows/goldseal-demo.yml"
- ".github/actions/verify-korgcert/**"
- ".github/workflows/korgcert-demo.yml"
# On main (post-merge): dogfood without commenting.
push:
branches: [main]
paths:
- "adapters/korg-seal/**"
- "adapters/korg-ledger-py/**"
- "spec/korg-ledger-v1/**"
- ".github/actions/verify-goldseal/**"
- ".github/workflows/goldseal-demo.yml"
- ".github/actions/verify-korgcert/**"
- ".github/workflows/korgcert-demo.yml"

permissions:
contents: read
pull-requests: write # so the Action can post the sticky Gold Seal comment
pull-requests: write # so the Action can post the sticky Certificate comment

jobs:
mint-and-verify:
Expand All @@ -48,41 +48,41 @@ jobs:
- name: Build a session ledger
run: python spec/korg-ledger-v1/tools/make_demo_session.py demo-session.jsonl

- name: Mint a Gold Seal (capture the issuer key)
- name: Mint a Certificate (capture the issuer key)
id: mint
run: |
python -m korg_seal mint demo-session.jsonl \
--claim "CI demo: agent added a /healthz endpoint with a passing test" \
--key issuer.ed25519 -o demo.goldseal.json
--key issuer.ed25519 -o demo.korgcert.json
echo "pub=$(python -m korg_seal key --key issuer.ed25519)" >> "$GITHUB_OUTPUT"

- name: Verify the Gold Seal — pinned to the issuer (must PASS)
uses: ./.github/actions/verify-goldseal
- name: Verify the Certificate — pinned to the issuer (must PASS)
uses: ./.github/actions/verify-korgcert
with:
path: demo.goldseal.json
path: demo.korgcert.json
pin-pubkey: ${{ steps.mint.outputs.pub }}

- name: A tampered seal must FAIL (negative test)
run: |
python - <<'PY'
import json
e = json.load(open("demo.goldseal.json"))
e = json.load(open("demo.korgcert.json"))
e["claim"] = "CI demo: agent fixed an unrelated critical security bug" # move the claim
json.dump(e, open("tampered.goldseal.json", "w"))
json.dump(e, open("tampered.korgcert.json", "w"))
PY
if node spec/korg-ledger-v1/js/verify.mjs tampered.goldseal.json; then
echo "::error::a tampered Gold Seal verified — this must never happen"
if node spec/korg-ledger-v1/js/verify.mjs tampered.korgcert.json; then
echo "::error::a tampered Certificate verified — this must never happen"
exit 1
fi
echo "✓ tampered Gold Seal correctly rejected"
echo "✓ tampered Certificate correctly rejected"

- name: Job summary
if: always()
run: |
{
echo "### 🛡️ korg Gold Seal — verified in CI"
echo "### 🛡️ korg Certificate — verified in CI"
echo ""
echo "Minted a Gold Seal from a session ledger and verified it with the independent"
echo "Minted a Certificate from a session ledger and verified it with the independent"
echo "verifier, pinned to issuer \`${{ steps.mint.outputs.pub }}\`. A tampered copy was"
echo "correctly rejected. Re-verify in a browser: <https://new1direction.github.io/korg/web/seal.html>"
} >> "$GITHUB_STEP_SUMMARY"
6 changes: 3 additions & 3 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
name: Deploy verifier to GitHub Pages

# Publishes the zero-install, client-side verifiers + the korg-ledger@v1 /
# goldseal@v1 specs. The Pages root is spec/korg-ledger-v1/, so:
# korgcert@v1 specs. The Pages root is spec/korg-ledger-v1/, so:
# / → landing page (index.html)
# /web/seal.html → the Gold Seal verifier
# /web/seal.html → the Certificate verifier
# /web/index.html → the raw-ledger verifier
# /js/verify.mjs → the conformance-pinned engine the pages import
on:
push:
branches: [main, feat/goldseal-certificate]
branches: [main, feat/korgcert-certificate]
paths: ["spec/korg-ledger-v1/**", ".github/workflows/pages.yml"]
workflow_dispatch:

Expand Down
2 changes: 1 addition & 1 deletion ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ Korg maintains a tamper-proof audit trail of every significant action using a cr
Beyond the in-process provenance chain above, Korg ships a set of independently-verifiable, "flight-recorder" capabilities that let third parties check an agent's work without trusting Korg itself:

- **`korg-ledger@v1`**: A frozen, hash-chained, HLC-ordered, tamper-evident event ledger with cross-language conformance (Rust/Python/JS). Each event carries an Ed25519 per-event signature, and the ledger supports git-tip structural anchoring for offline structural verification.
- **Gold Seal (`goldseal@v1`)**: A public, independently-verifiable certificate of agent work, produced by the `korg-seal` CLI (mint/anchor/resolve/verify) and checkable by three conformant verifiers (`korg-verify` in Rust, plus Python and JS) as well as zero-install in-browser verifiers hosted on GitHub Pages.
- **Certificate (`korgcert@v1`)**: A public, independently-verifiable certificate of agent work, produced by the `korg-seal` CLI (mint/anchor/resolve/verify) and checkable by three conformant verifiers (`korg-verify` in Rust, plus Python and JS) as well as zero-install in-browser verifiers hosted on GitHub Pages.
- **Honest `korg run-once` pipeline**: Runs a real patch through a real `cargo check` and attests a mutation count that *equals* the real `git diff` (file count + changed paths). When it cannot produce a real result, it reports an honest null rather than fabricating one.
- **Provider model**: The default is a hermetic `DeterministicProvider` (fixture-only); `--provider ollama` runs a live local model on arbitrary tasks.

Expand Down
Loading
Loading