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
53 changes: 53 additions & 0 deletions web-ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions web-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-tooltip": "^1.2.8",
"@tailwindcss/typography": "^0.5.19",
"axios": "^1.6.5",
"class-variance-authority": "^0.7.0",
Expand Down
122 changes: 118 additions & 4 deletions web-ui/src/app/proof/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { useState, useEffect } from 'react';
import Link from 'next/link';
import useSWR from 'swr';
import { InformationCircleIcon } from '@hugeicons/react';
import {
Dialog,
DialogContent,
Expand All @@ -13,6 +14,12 @@ import {
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import {
Tooltip,
TooltipTrigger,
TooltipContent,
TooltipProvider,
} from '@/components/ui/tooltip';
import { ProofStatusBadge } from '@/components/proof';
import { proofApi } from '@/lib/api';
import { getSelectedWorkspacePath } from '@/lib/workspace-storage';
Expand Down Expand Up @@ -143,12 +150,14 @@ export default function ProofPage() {
}

return (
<TooltipProvider>
<main className="min-h-screen bg-background">
<div className="mx-auto max-w-7xl px-4 py-8">
<div className="mb-6">
<h1 className="text-2xl font-bold">PROOF9 Requirements</h1>
<p className="mt-1 text-sm text-muted-foreground">
Quality memory — requirements captured from glitches, proven through evidence.
PROOF9 tracks quality requirements with evidence. Requirements must be satisfied or waived before shipping.{' '}
<a href="#proof9-help" className="text-primary hover:underline">Learn more ↓</a>
</p>
</div>

Expand Down Expand Up @@ -184,15 +193,67 @@ export default function ProofPage() {
<span className="font-medium text-foreground">{data.total} total</span>
</div>

{/* Status legend */}
<div className="mb-4 flex flex-wrap gap-4 text-sm text-muted-foreground">
<span className="flex items-center gap-1.5">
<span className="h-2.5 w-2.5 rounded-full bg-red-400" />
<span><span className="font-medium text-foreground">open</span> — must be satisfied before shipping</span>
</span>
<span className="flex items-center gap-1.5">
<span className="h-2.5 w-2.5 rounded-full bg-green-400" />
<span><span className="font-medium text-foreground">satisfied</span> — proven with collected evidence</span>
</span>
<span className="flex items-center gap-1.5">
<span className="h-2.5 w-2.5 rounded-full bg-gray-400" />
<span><span className="font-medium text-foreground">waived</span> — approved exception, no evidence required</span>
</span>
</div>

<div className="overflow-x-auto rounded-lg border">
<table className="min-w-[800px] w-full text-sm">
<thead className="border-b bg-muted/50">
<tr>
<th className="px-4 py-3 text-left font-medium">ID</th>
<th className="px-4 py-3 text-left font-medium">Title</th>
<th className="px-4 py-3 text-left font-medium">Glitch Type</th>
<th className="px-4 py-3 text-left font-medium">Severity</th>
<th className="px-4 py-3 text-left font-medium">Gates</th>
<th className="px-4 py-3 text-left font-medium">
<span className="flex items-center gap-1">
Glitch Type
<Tooltip>
<TooltipTrigger asChild>
<button type="button" aria-label="Explain Glitch Type" className="inline-flex cursor-help text-muted-foreground/60 hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2">
<InformationCircleIcon className="h-3.5 w-3.5" aria-hidden="true" />
</button>
</TooltipTrigger>
<TooltipContent>The category of quality issue this requirement addresses</TooltipContent>
</Tooltip>
</span>
</th>
<th className="px-4 py-3 text-left font-medium">
<span className="flex items-center gap-1">
Severity
<Tooltip>
<TooltipTrigger asChild>
<button type="button" aria-label="Explain Severity" className="inline-flex cursor-help text-muted-foreground/60 hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2">
<InformationCircleIcon className="h-3.5 w-3.5" aria-hidden="true" />
</button>
</TooltipTrigger>
<TooltipContent>Impact level: critical, high, medium, or low</TooltipContent>
</Tooltip>
</span>
</th>
<th className="px-4 py-3 text-left font-medium">
<span className="flex items-center gap-1">
Gates
<Tooltip>
<TooltipTrigger asChild>
<button type="button" aria-label="Explain Gates" className="inline-flex cursor-help text-muted-foreground/60 hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2">
<InformationCircleIcon className="h-3.5 w-3.5" aria-hidden="true" />
</button>
</TooltipTrigger>
<TooltipContent>Number of evidence gates that must pass to satisfy this requirement</TooltipContent>
</Tooltip>
</span>
</th>
<th className="px-4 py-3 text-left font-medium">Status</th>
<th className="px-4 py-3 text-left font-medium">Created</th>
<th className="px-4 py-3 text-left font-medium"></th>
Expand Down Expand Up @@ -252,7 +313,60 @@ export default function ProofPage() {
}}
/>
)}

{/* In-page help reference */}
<section id="proof9-help" className="mt-12 rounded-lg border bg-muted/30 p-6">
<h2 className="mb-3 text-base font-semibold">About PROOF9</h2>
<p className="mb-4 text-sm text-muted-foreground">
PROOF9 is CodeFRAME&apos;s quality memory system. It captures requirements from past glitches and failures,
then enforces that each requirement is <em>proven</em> through evidence before code ships. This creates a
self-reinforcing quality loop: every bug becomes a permanent gate.
</p>
<div className="grid gap-4 text-sm sm:grid-cols-2">
<div>
<h3 className="mb-1.5 font-medium">Key Terms</h3>
<dl className="space-y-2 text-muted-foreground">
<div>
<dt className="font-medium text-foreground">Glitch Type</dt>
<dd>The category of quality issue a requirement addresses (e.g., regression, security, performance).</dd>
</div>
<div>
<dt className="font-medium text-foreground">Severity</dt>
<dd>Impact level — <strong>critical</strong> blocks ship, <strong>high</strong> strongly recommended, <strong>medium/low</strong> advisory.</dd>
</div>
<div>
<dt className="font-medium text-foreground">Gates / Obligations</dt>
<dd>Evidence rules — specific tests or checks that must pass to satisfy a requirement.</dd>
</div>
</dl>
</div>
<div>
<h3 className="mb-1.5 font-medium">Requirement Lifecycle</h3>
<dl className="space-y-2 text-muted-foreground">
<div>
<dt className="flex items-center gap-1.5 font-medium text-foreground">
<span className="h-2 w-2 rounded-full bg-red-400" /> open
</dt>
<dd>Not yet satisfied. Must be resolved (satisfied or waived) before shipping.</dd>
</div>
<div>
<dt className="flex items-center gap-1.5 font-medium text-foreground">
<span className="h-2 w-2 rounded-full bg-green-400" /> satisfied
</dt>
<dd>Evidence collected. All obligation gates passed.</dd>
</div>
<div>
<dt className="flex items-center gap-1.5 font-medium text-foreground">
<span className="h-2 w-2 rounded-full bg-gray-400" /> waived
</dt>
<dd>Approved exception with a recorded reason. No evidence required.</dd>
</div>
</dl>
</div>
</div>
</section>
</div>
</main>
</TooltipProvider>
);
}
36 changes: 36 additions & 0 deletions web-ui/src/components/ui/tooltip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use client';

import * as React from 'react';
import * as TooltipPrimitive from '@radix-ui/react-tooltip';

import { cn } from '@/lib/utils';

const TooltipProvider = TooltipPrimitive.Provider;

const Tooltip = TooltipPrimitive.Root;

const TooltipTrigger = TooltipPrimitive.Trigger;

const TooltipContent = React.forwardRef<
React.ComponentRef<typeof TooltipPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
>(({ className, sideOffset = 4, ...props }, ref) => (
<TooltipPrimitive.Portal>
<TooltipPrimitive.Content
ref={ref}
sideOffset={sideOffset}
className={cn(
'z-50 max-w-xs rounded-md border bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-md',
'animate-in fade-in-0 zoom-in-95',
'data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95',
'data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2',
'data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
className
)}
{...props}
/>
</TooltipPrimitive.Portal>
));
TooltipContent.displayName = TooltipPrimitive.Content.displayName;

export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
Loading