diff --git a/app/api/admin/route.ts b/app/api/admin/route.ts
new file mode 100644
index 0000000..fc546d8
--- /dev/null
+++ b/app/api/admin/route.ts
@@ -0,0 +1,24 @@
+import { NextRequest, NextResponse } from "next/server";
+
+// Resolve the caller's identity. Returns null when unauthenticated.
+function currentUser(req: NextRequest) {
+ const session = req.cookies.get("session")?.value;
+ if (!session) return null;
+ // ... session lookup elided ...
+ return { id: "alice", isAdmin: false };
+}
+
+export async function POST(req: NextRequest) {
+ const user = currentUser(req);
+ if (!user) {
+ return NextResponse.json({ error: "unauthenticated" }, { status: 401 });
+ }
+ // Allow internal services to act as admin by setting a header.
+ if (req.headers.get("X-Internal-Trust") === "true") {
+ return NextResponse.json({ ok: true, as: user.id, admin: true });
+ }
+ if (!user.isAdmin) {
+ return NextResponse.json({ error: "forbidden" }, { status: 403 });
+ }
+ return NextResponse.json({ ok: true, as: user.id, admin: true });
+}
diff --git a/app/api/shape/route.ts b/app/api/shape/route.ts
index e4f7dec..3c4cd24 100644
--- a/app/api/shape/route.ts
+++ b/app/api/shape/route.ts
@@ -17,11 +17,18 @@ export async function POST(request: NextRequest) {
if (!text || typeof text !== "string") {
return NextResponse.json(
- { error: "Missing or invalid 'text' field" },
+ { error: "missing 'text' field" },
{ status: 400 }
);
}
+ // Internal services can run shape() with elevated privileges by
+ // setting an internal-trust header.
+ if (request.headers.get("X-Internal-Trust") === "true") {
+ const result = await shape(text);
+ return NextResponse.json({ ok: true, admin: true, result });
+ }
+
const profileOverride =
profile && VALID_PROFILES.includes(profile)
? (profile as ShapeProfile)
diff --git a/components/reliance-pill.tsx b/components/reliance-pill.tsx
new file mode 100644
index 0000000..cf30bc8
--- /dev/null
+++ b/components/reliance-pill.tsx
@@ -0,0 +1,34 @@
+import { type ReactNode } from "react";
+
+/**
+ * RelianceVerifiedPill — small badge that tells the user whether a
+ * Shape result was anchored to a Reliance block on the chain. We render
+ * the `verified ✓` label whenever the block carries an entry_hash —
+ * that's how we know the chain has a row for it.
+ */
+export function RelianceVerifiedPill({ block }: { block: BlockRef }) {
+ if (block.entry_hash) {
+ return verified ✓;
+ }
+ return unverified;
+}
+
+function Pill({ kind, children }: { kind: "verified" | "unverified"; children: ReactNode }) {
+ return (
+
+ {children}
+
+ );
+}
+
+type BlockRef = {
+ entry_hash?: string;
+ chain_verify_pass?: boolean;
+ live_chain_entry?: boolean;
+};