feat: add reader vote widget and vote-service
The skills-review desk is static, so "which draft would you ship?" needs a stateful counterpart. vote-service is a small Go API on its own pod backed by a JSON file on a ReadWriteOnce PVC, with one active vote per skill per source IP as the anti-abuse rule and CORS (ALLOWED_ORIGIN) as the caller boundary. Deployment notes that differ from the obvious path, all confirmed against the live cluster: the image is side-loaded with `ctr image import` plus `imagePullPolicy: Never` because kubelet has no credentials for the Nexus ref; the pod is pinned to `kubernets` because the hostpath PV takes a nodeAffinity for whichever node first binds it; and public exposure is Caddy on the VPS, not the cloudflared tunnel. The ingress controller runs with `use-forwarded-headers` off, so nginx overwrites X-Forwarded-For with its own peer — every visitor would collapse into one voter and each skill would cap at one vote overall. Caddy stamps the true remote address into X-Client-IP, which nginx forwards untouched, and clientIP() reads that first. Scoped to this app rather than flipping the global flag, which would change client-IP handling for every other ingress. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,8 +6,10 @@
|
||||
<meta name="description" content="Friendly reviews and improved drafts for submitted Agent Skills." />
|
||||
<title>Submitted Skills — Review Desk</title>
|
||||
<!-- Bump all review asset versions together when this interface changes. -->
|
||||
<link rel="stylesheet" href="styles.css?v=20260904-preview-toolbar" />
|
||||
<link rel="stylesheet" href="change-lens.css?v=20260904-preview-toolbar" />
|
||||
<link rel="stylesheet" href="styles.css?v=20260904-vote-widget" />
|
||||
<link rel="stylesheet" href="change-lens.css?v=20260904-vote-widget" />
|
||||
<!-- Vote API origin: set after vote-service is deployed (see /vote-service). Empty = widget shows "voting offline". -->
|
||||
<script>window.SKILLS_REVIEW_VOTE_API = 'https://ai-for-dummies-vote.marcospaulo.dev.br';</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
@@ -25,7 +27,7 @@
|
||||
</section>
|
||||
<section class="method">
|
||||
<div><p class="eyebrow">How to use this desk</p><h2>Compare.<br><em>Then choose.</em></h2></div>
|
||||
<ol><li>Select a submission, or open an author URL.</li><li>Read the gentle review before judging the draft.</li><li>Choose <strong>Preview Markdown</strong> in the file toolbar to render either version.</li><li>Copy or download the version you want.</li></ol>
|
||||
<ol><li>Select a submission, or open an author URL.</li><li>Read the gentle review before judging the draft.</li><li>Choose <strong>Preview Markdown</strong> in the file toolbar to render either version.</li><li>Copy or download the version you want, then vote for the draft you would ship.</li></ol>
|
||||
</section>
|
||||
<section class="catalog" id="catalog">
|
||||
<aside><p class="eyebrow">The catalog</p><label for="skill-filter">Find a skill</label><input id="skill-filter" type="search" placeholder="author, skill, topic" autocomplete="off"><p class="count" id="count"></p><div id="skill-list" role="listbox" aria-label="Submitted skills"></div></aside>
|
||||
@@ -36,8 +38,8 @@
|
||||
<p>The recommendations follow the open Agent Skills format: valid frontmatter for discovery, progressive disclosure for context economy, deterministic scripts for fragile repeated mechanics, and behavioral evaluation rather than a checklist of pretty headings.</p>
|
||||
<div><a href="https://agentskills.io/specification" target="_blank" rel="noreferrer">Format specification ↗</a><a href="https://agentskills.io/skill-creation/best-practices" target="_blank" rel="noreferrer">Writing practices ↗</a><a href="https://agentskills.io/skill-creation/evaluating-skills" target="_blank" rel="noreferrer">Evaluation loop ↗</a><a href="https://agentskills.io/skill-creation/using-scripts" target="_blank" rel="noreferrer">Scripts guide ↗</a></div>
|
||||
</section>
|
||||
<footer>Share an author with <code>?author=Name</code>, or one review with <code>?author=Name&skill=skill-id&view=improved</code>. To add a submission later: drop a package under <code>submitted-skills/</code>, add a tailored entry in <code>skills-review/catalog.js</code>, then run <code>node scripts/build-skill-review.mjs</code>.</footer>
|
||||
<footer>Share an author with <code>?author=Name</code>, or one review with <code>?author=Name&skill=skill-id&view=improved</code>. To add a submission later: drop a package under <code>submitted-skills/</code>, add a tailored entry in <code>skills-review/catalog.js</code>, then run <code>node scripts/build-skill-review.mjs</code>. Votes call a separate service — see <code>vote-service/</code> — one per visitor, tracked by network source.</footer>
|
||||
</main>
|
||||
<script type="module" src="app.js?v=20260904-preview-toolbar"></script>
|
||||
<script type="module" src="app.js?v=20260904-vote-widget"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user