-
Notifications
You must be signed in to change notification settings - Fork 0
Add Safe owner list invariants research page #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4526bad
934c77e
87f4a99
e77b635
5a6392d
0cc0c5a
c9afafb
25a1c88
b2f4b7a
3990fff
d548284
dbcdbf3
33f9da6
7e43941
4535f42
e1fbac6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| name: CI | ||
|
|
||
| on: | ||
| pull_request: | ||
| paths-ignore: | ||
| - 'README.md' | ||
| - 'CLAUDE.md' | ||
| - 'agent.md' | ||
| push: | ||
| branches: | ||
| - main | ||
| paths-ignore: | ||
| - 'README.md' | ||
| - 'CLAUDE.md' | ||
| - 'agent.md' | ||
|
|
||
| env: | ||
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | ||
| NEXT_TELEMETRY_DISABLED: 1 | ||
|
|
||
| concurrency: | ||
| group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| build: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 | ||
|
|
||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v6 | ||
|
|
||
| - name: Setup Bun | ||
| uses: oven-sh/setup-bun@v2 | ||
| with: | ||
| bun-version: 1.3.9 | ||
|
|
||
| - name: Restore Next.js cache | ||
| uses: actions/cache@v5 | ||
| with: | ||
| path: .next/cache | ||
| key: ${{ runner.os }}-nextjs-${{ hashFiles('bun.lock', 'package.json') }}-${{ hashFiles('pages/**/*', 'components/**/*', 'lib/**/*', 'data/**/*', 'styles/**/*', 'content/**/*', 'public/**/*', 'next.config.js', 'postcss.config.js', 'tailwind.config.js') }} | ||
| restore-keys: | | ||
| ${{ runner.os }}-nextjs-${{ hashFiles('bun.lock', 'package.json') }}- | ||
|
|
||
| - name: Install dependencies | ||
| run: bun install --frozen-lockfile | ||
|
|
||
| - name: Build site | ||
| run: bun run build |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| export default function Hypothesis({ | ||
| name, | ||
| constraint, | ||
| source, | ||
| children, | ||
| border = true | ||
| }) { | ||
| return ( | ||
| <li | ||
| className={`list-none ${border ? 'border-b border-gray-200/50' : ''}`} | ||
| > | ||
| <details className="group/hyp"> | ||
| <summary className="px-5 py-3 cursor-pointer select-none list-none flex items-center gap-3 [&::-webkit-details-marker]:hidden"> | ||
| <svg | ||
| viewBox="0 0 24 24" | ||
| className="w-3.5 h-3.5 text-muted/50 transition-transform group-open/hyp:rotate-90 flex-shrink-0" | ||
| fill="none" | ||
| stroke="currentColor" | ||
| strokeWidth="1.5" | ||
| strokeLinecap="round" | ||
| strokeLinejoin="round" | ||
| > | ||
| <polyline points="9 6 15 12 9 18" /> | ||
| </svg> | ||
| <code className="font-mono text-[12px] font-medium">{name}</code> | ||
| <span className="text-muted text-[13px]">{constraint}</span> | ||
| </summary> | ||
| <div className="px-5 pb-3 pl-12 text-[13px] text-muted leading-relaxed"> | ||
| <p className="mb-1"> | ||
| <span className="text-[11px] font-mono uppercase tracking-wider text-muted/60"> | ||
| {source} | ||
| </span> | ||
| </p> | ||
| <p>{children}</p> | ||
| </div> | ||
| </details> | ||
| </li> | ||
| ) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| import { useState, useEffect, useRef } from 'react' | ||
|
|
||
| const FORMAL_INVARIANTS = [ | ||
| '\u2200 key, next(key) \u2260 0 \u2192 reachable(SENTINEL, key)', | ||
| '\u2200 key \u2260 0, next(key) \u2260 0 \u2194 reachable(SENTINEL, key)', | ||
| '\u2200 a b, reachable(a, b) \u2227 reachable(b, a) \u2192 a = b' | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Formal invariant displays property page says is falseMedium Severity The third entry in Additional Locations (1)Reviewed by Cursor Bugbot for commit e1fbac6. Configure here. |
||
| ] | ||
|
|
||
| export default function SafeGuarantee() { | ||
| const [showEnglish, setShowEnglish] = useState(true) | ||
| const timerRef = useRef(null) | ||
|
|
||
| useEffect(() => { | ||
| timerRef.current = setTimeout(() => setShowEnglish(false), 5000) | ||
| return () => clearTimeout(timerRef.current) | ||
| }, []) | ||
|
|
||
| const handleToggle = () => { | ||
| if (timerRef.current) { | ||
| clearTimeout(timerRef.current) | ||
| timerRef.current = null | ||
| } | ||
| setShowEnglish((prev) => !prev) | ||
| } | ||
|
|
||
| return ( | ||
| <div className="py-6"> | ||
| <button | ||
| onClick={handleToggle} | ||
| className="inline-flex items-center gap-1.5 text-[12px] font-semibold text-muted hover:text-heading transition-colors cursor-pointer mb-4" | ||
| > | ||
| <svg | ||
| viewBox="0 0 24 24" | ||
| className="w-[13px] h-[13px]" | ||
| fill="none" | ||
| stroke="currentColor" | ||
| strokeWidth="1.5" | ||
| strokeLinecap="round" | ||
| strokeLinejoin="round" | ||
| > | ||
| <path d="m5 8 6 6" /> | ||
| <path d="m4 14 6-6 2-3" /> | ||
| <path d="M2 5h12" /> | ||
| <path d="M7 2h1" /> | ||
| <path d="m22 22-5-10-5 10" /> | ||
| <path d="M14 18h6" /> | ||
| </svg> | ||
| {showEnglish ? 'Switch to formal' : 'Switch to English'} | ||
| </button> | ||
|
|
||
| <div className="grid text-center [&>*]:col-start-1 [&>*]:row-start-1"> | ||
| <div | ||
| className="flex flex-col items-center justify-center gap-4 md:gap-5 transition-opacity duration-200 text-[0.945rem] md:text-[1.18125rem] font-mono text-primary leading-snug" | ||
| style={{ | ||
| opacity: showEnglish ? 0 : 1, | ||
| pointerEvents: showEnglish ? 'none' : 'auto' | ||
| }} | ||
| aria-hidden={showEnglish} | ||
| > | ||
| {FORMAL_INVARIANTS.map((formal, i) => ( | ||
| <code | ||
| key={i} | ||
| className="block w-full max-w-full overflow-x-auto px-1" | ||
| > | ||
| {formal} | ||
| </code> | ||
| ))} | ||
| </div> | ||
| <div | ||
| className="flex items-center justify-center transition-opacity duration-200" | ||
| style={{ | ||
| opacity: showEnglish ? 1 : 0, | ||
| pointerEvents: showEnglish ? 'auto' : 'none' | ||
| }} | ||
| aria-hidden={!showEnglish} | ||
| > | ||
| <p className="text-xl md:text-2xl leading-snug font-serif max-w-prose mx-auto px-1"> | ||
| The owners mapping forms a proper loop-free circular linked list. | ||
| </p> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| ) | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SafeGuarantee duplicates Guarantee toggle logic and structureLow Severity
Reviewed by Cursor Bugbot for commit 934c77e. Configure here. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| import { useEffect, useRef } from 'react' | ||
|
|
||
| export default function TikZDiagram({ tikz, className = '' }) { | ||
| const ref = useRef(null) | ||
|
|
||
| useEffect(() => { | ||
| const container = ref.current | ||
| if (!container) return | ||
|
|
||
| // Add TikZJax fonts CSS if not already present | ||
| if (!document.querySelector('link[href*="tikzjax.com"]')) { | ||
| const link = document.createElement('link') | ||
| link.rel = 'stylesheet' | ||
| link.type = 'text/css' | ||
| link.href = 'https://tikzjax.com/v1/fonts.css' | ||
| document.head.appendChild(link) | ||
| } | ||
|
|
||
| // Create the <script type="text/tikz"> element | ||
| const tikzEl = document.createElement('script') | ||
| tikzEl.type = 'text/tikz' | ||
| tikzEl.textContent = tikz | ||
| container.appendChild(tikzEl) | ||
|
|
||
| const existingScript = document.querySelector('script[src*="tikzjax.com"]') | ||
| if (!existingScript) { | ||
| // First load: add tikzjax.js — it sets window.onload to its processing | ||
| // function, but in a SPA that event already fired, so we call it manually. | ||
| const script = document.createElement('script') | ||
| script.src = 'https://tikzjax.com/v1/tikzjax.js' | ||
| script.onload = () => { | ||
| if (typeof window.onload === 'function') { | ||
| window.onload() | ||
| } | ||
| } | ||
| document.head.appendChild(script) | ||
| } else { | ||
| // Already loaded: call the handler again to process new elements | ||
| if (typeof window.onload === 'function') { | ||
| window.onload() | ||
| } | ||
| } | ||
|
|
||
| return () => { | ||
| container.innerHTML = '' | ||
| } | ||
| }, [tikz]) | ||
|
|
||
| return <div ref={ref} className={className} /> | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| import { research } from '../data/research' | ||
|
|
||
| export function getSortedResearch() { | ||
| return [...research].sort((a, b) => b.date.localeCompare(a.date)) | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nexus Mutual page missed
|
||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New shared Hypothesis duplicates existing inline component
Low Severity
The newly extracted
components/research/Hypothesis.jsxis an exact duplicate of the inlineHypothesisfunction still present inpages/research/nexus-mutual-book-value.jsx(lines 11–43). The Lido page was refactored to use the shared component, but the Nexus Mutual page was missed, leaving two identical implementations. Any future fix to one copy risks not being applied to the other.Reviewed by Cursor Bugbot for commit e1fbac6. Configure here.