← back to AbramsEgo
fix: canary verdict extraction handles worst_verdict/results/tokens/ok-flag/baseline shapes (smoke gate green)
80890c8b77d23e607953df94d1ee664edaa86baf · 2026-08-02 01:02:52 -0700 · Steve
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Files touched
A build-queue/done/50-affiliate-research.mdA build-queue/failed/50-affiliate-research.mdA build-queue/tasks/50-affiliate-research-verify-fix.mdA build-queue/tasks/51-affiliate-cabinet-select.mdA build-queue/tasks/52-affiliate-draft-and-kits.mdA build-queue/tasks/53-a2a-protocol-scope.mdM server.js
Diff
commit 80890c8b77d23e607953df94d1ee664edaa86baf
Author: Steve <steve@designerwallcoverings.com>
Date: Sun Aug 2 01:02:52 2026 -0700
fix: canary verdict extraction handles worst_verdict/results/tokens/ok-flag/baseline shapes (smoke gate green)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---
build-queue/done/50-affiliate-research.md | 34 ++++++++++++++++++++
build-queue/failed/50-affiliate-research.md | 34 ++++++++++++++++++++
.../tasks/50-affiliate-research-verify-fix.md | 5 +++
build-queue/tasks/51-affiliate-cabinet-select.md | 25 +++++++++++++++
build-queue/tasks/52-affiliate-draft-and-kits.md | 37 ++++++++++++++++++++++
build-queue/tasks/53-a2a-protocol-scope.md | 23 ++++++++++++++
server.js | 21 +++++++-----
7 files changed, 171 insertions(+), 8 deletions(-)
diff --git a/build-queue/done/50-affiliate-research.md b/build-queue/done/50-affiliate-research.md
new file mode 100644
index 0000000..202baa4
--- /dev/null
+++ b/build-queue/done/50-affiliate-research.md
@@ -0,0 +1,34 @@
+# AbramsEgo task 50 — RESEARCH high-commission affiliate programs (engine 2) — TK-10132
+
+Single-purpose research node. Do ONLY this; do not draft the registry or the memo (that is task 52).
+
+GOAL: find real affiliate/referral programs that fit AbramsEgo's audience — solo operators /
+agencies who run AI-agent fleets, self-host dashboards, do design/creator work — with
+GENUINELY HIGH commissions, and VERIFY the numbers instead of trusting marketing copy.
+
+AUDIENCE-FIT categories to mine: cloud/VPS hosting, uptime/log monitoring, AI-tool/API
+platforms (LLM, TTS, image), dev tooling, domains/DNS, design marketplaces & asset stores,
+no-code/automation, email/CRM. Aim for ~15-20 candidates spanning ≥5 categories.
+
+For EACH candidate capture (leave a field null if you cannot verify it — never invent):
+- slug, label, category
+- program name + JOIN URL (the actual affiliate/partner signup page)
+- commission: rate (% or flat $), whether recurring vs one-time, and the SOURCE URL you read it from
+- cookie/attribution window (days)
+- payout threshold + method
+- approval type: instant / manual-review
+- trust note: how established the program is; any red flags
+- why_fit: one line on why this suits the AbramsEgo audience
+
+RAILS (hard):
+- READ-ONLY web research. NEVER create an account, submit a form, or sign up for anything.
+- Metered web/Exa research is capped at $0.50 total for this task — stop when you hit it.
+ Log the spend to the cost-tracker skill (~/.claude/skills/cost-tracker/log.js) and print the
+ running total. Prefer local reasoning; use paid search only to verify real numbers.
+- Do NOT touch affiliates.json, the ads engine, AD_NETWORK_PUB_ID, pm2, or git history beyond
+ the one commit below.
+
+OUTPUT: write all candidates as one JSON object per line to `data/affiliate-research.jsonl`
+(create it). Then `git add data/affiliate-research.jsonl && git commit -m "research: candidate
+affiliate programs w/ verified commissions (engine 2, TK-10132)"` (author steve@designerwallcoverings.com).
+Print a short table of what you found + total research $ spent.
diff --git a/build-queue/failed/50-affiliate-research.md b/build-queue/failed/50-affiliate-research.md
new file mode 100644
index 0000000..202baa4
--- /dev/null
+++ b/build-queue/failed/50-affiliate-research.md
@@ -0,0 +1,34 @@
+# AbramsEgo task 50 — RESEARCH high-commission affiliate programs (engine 2) — TK-10132
+
+Single-purpose research node. Do ONLY this; do not draft the registry or the memo (that is task 52).
+
+GOAL: find real affiliate/referral programs that fit AbramsEgo's audience — solo operators /
+agencies who run AI-agent fleets, self-host dashboards, do design/creator work — with
+GENUINELY HIGH commissions, and VERIFY the numbers instead of trusting marketing copy.
+
+AUDIENCE-FIT categories to mine: cloud/VPS hosting, uptime/log monitoring, AI-tool/API
+platforms (LLM, TTS, image), dev tooling, domains/DNS, design marketplaces & asset stores,
+no-code/automation, email/CRM. Aim for ~15-20 candidates spanning ≥5 categories.
+
+For EACH candidate capture (leave a field null if you cannot verify it — never invent):
+- slug, label, category
+- program name + JOIN URL (the actual affiliate/partner signup page)
+- commission: rate (% or flat $), whether recurring vs one-time, and the SOURCE URL you read it from
+- cookie/attribution window (days)
+- payout threshold + method
+- approval type: instant / manual-review
+- trust note: how established the program is; any red flags
+- why_fit: one line on why this suits the AbramsEgo audience
+
+RAILS (hard):
+- READ-ONLY web research. NEVER create an account, submit a form, or sign up for anything.
+- Metered web/Exa research is capped at $0.50 total for this task — stop when you hit it.
+ Log the spend to the cost-tracker skill (~/.claude/skills/cost-tracker/log.js) and print the
+ running total. Prefer local reasoning; use paid search only to verify real numbers.
+- Do NOT touch affiliates.json, the ads engine, AD_NETWORK_PUB_ID, pm2, or git history beyond
+ the one commit below.
+
+OUTPUT: write all candidates as one JSON object per line to `data/affiliate-research.jsonl`
+(create it). Then `git add data/affiliate-research.jsonl && git commit -m "research: candidate
+affiliate programs w/ verified commissions (engine 2, TK-10132)"` (author steve@designerwallcoverings.com).
+Print a short table of what you found + total research $ spent.
diff --git a/build-queue/tasks/50-affiliate-research-verify-fix.md b/build-queue/tasks/50-affiliate-research-verify-fix.md
new file mode 100644
index 0000000..cbf309b
--- /dev/null
+++ b/build-queue/tasks/50-affiliate-research-verify-fix.md
@@ -0,0 +1,5 @@
+# VERIFY-FIX for 50-affiliate-research.md (smoke gate failed after it reported DONE)
+The prior task claimed success but scripts/smoke.sh FAILED against the running
+:9773 instance. Read build-queue/logs for the smoke output, find what broke,
+fix it surgically, `pm2 restart abramsego`, and re-run scripts/smoke.sh until it
+passes. Original task is in build-queue/needs-fix/50-affiliate-research.md. Commit the fix.
diff --git a/build-queue/tasks/51-affiliate-cabinet-select.md b/build-queue/tasks/51-affiliate-cabinet-select.md
new file mode 100644
index 0000000..1265872
--- /dev/null
+++ b/build-queue/tasks/51-affiliate-cabinet-select.md
@@ -0,0 +1,25 @@
+# AbramsEgo task 51 — A2A CABINET selects the top affiliate vendors — TK-10132
+
+Depends on task 50's output `data/affiliate-research.jsonl`. If that file is missing or empty,
+write `data/affiliate-selection.json` as `{"error":"no research input","selected":[]}` and stop.
+
+This is the "consult with A2A for best methods" node — INTERNAL agent-to-agent consultation
+(the real A2A protocol is scoped separately in task 53). Run it on LOCAL models ($0):
+
+1. Use /dtd (Debate Team Decide) to COMMIT a ranking of the researched candidates. Rank by a
+ blended score: commission value (weight recurring > one-time) × audience-fit × program trust
+ × cookie-window length. Verified-number candidates outrank unverified ones.
+2. Have vp-abramsego (the officer) sign off on the shortlist, and run the `contrarian` agent to
+ red-team it ("are these actually high-commission, actually reputable, actually relevant — or
+ just the ones with the loudest marketing?"). Fold the dissent in.
+3. Select the top 6-8. Drop any candidate whose commission rate could NOT be verified (leave it
+ in a `deferred` list with the reason, don't silently keep it).
+
+RAILS: read + reason only. No signups, no registry writes, no active flips, no spend beyond the
+local models. Do not deploy or push.
+
+OUTPUT: write `data/affiliate-selection.json`:
+{ "selected": [ {slug, label, category, commission, cookie_days, approval, join_url,
+ score, rationale} ], "deferred": [ {slug, reason} ], "dissent": "<contrarian's strongest
+ surviving objection>" }
+Then commit `select: cabinet-ranked top affiliate vendors (TK-10132)`. Print the ranked list.
diff --git a/build-queue/tasks/52-affiliate-draft-and-kits.md b/build-queue/tasks/52-affiliate-draft-and-kits.md
new file mode 100644
index 0000000..d5431f6
--- /dev/null
+++ b/build-queue/tasks/52-affiliate-draft-and-kits.md
@@ -0,0 +1,37 @@
+# AbramsEgo task 52 — DRAFT registry entries + one-click join kits + activation memo — TK-10132
+
+Depends on task 51's `data/affiliate-selection.json`. If missing/empty, do nothing and exit 0.
+
+Turn the cabinet's selection into ready-to-activate registry entries + a single approval memo.
+Read data/affiliates.json first and preserve the existing 6 seed entries — APPEND, never replace.
+
+1. For each `selected` vendor, append an entry to `data/affiliates.json` with:
+ { slug, label, url (the vendor's plain product page for now), program, category,
+ commission, cookie_days, note, added:"<today>", "status":"draft" }
+ The `note` MUST carry the verified commission + cookie window so it shows on the dashboard.
+ HARD: every new entry is status:"draft". NEVER write status:"active" — activation is Steve's
+ switch after he actually joins the program (identity/account step).
+
+2. Write per-vendor ONE-CLICK JOIN KITS to `data/affiliate-join-kits.md` — for each vendor:
+ - the exact JOIN URL
+ - the 3-5 steps to join
+ - EXACTLY where, once approved, Steve pastes his real tracking/affiliate URL back into
+ data/affiliates.json (the `url` field) and flips `status` to `active` — so the /go/<slug>
+ redirect then carries his real link.
+
+3. Write ONE consolidated approval memo to
+ ~/.claude/yolo-queue/pending-approval/affiliate-activation-TK-10132.md :
+ - table of the N proposed vendors (commission, cookie, approval type, join URL)
+ - the cabinet rationale + the contrarian dissent from task 51
+ - an officer (vp-abramsego) APPROVE / REVISE / BLOCK block
+ - explicit note: activating = Steve joins each program + pastes tracking URL + flips active;
+ no money/identity action was taken autonomously.
+
+RAILS: no signups, no active flips, no ads-engine/AD_NETWORK_PUB_ID changes, no deploy, no push.
+
+4. VERIFY: `pm2 restart abramsego`; for one new slug, `curl -s -o /dev/null -w "%{http_code}"
+ -u admin:'DW2024!' http://127.0.0.1:9773/go/<slug>` returns 302 and a row appends to
+ data/affiliate-clicks.jsonl. Confirm GET /api/affiliates lists the new drafts and the
+ affiliate engine pill is STILL "gated" (0 active). Commit
+ `feat(affiliate): draft high-commission vendors + join kits; activation gated (TK-10132)`.
+ Print the new draft count + the pending-approval memo path.
diff --git a/build-queue/tasks/53-a2a-protocol-scope.md b/build-queue/tasks/53-a2a-protocol-scope.md
new file mode 100644
index 0000000..ae28132
--- /dev/null
+++ b/build-queue/tasks/53-a2a-protocol-scope.md
@@ -0,0 +1,23 @@
+# AbramsEgo task 53 — SCOPE the real Agent2Agent (A2A) protocol — TK-10132
+
+Steve wants agents to "consult with A2A for best methods." Task 51 used the INTERNAL cabinet
+panel. This task SCOPES ONLY the real, external A2A protocol — do NOT install deps, do NOT
+open network endpoints, do NOT wire it live. Produce a decision-ready memo.
+
+Research (read-only, prefer local reasoning; ≤$0.25 metered if needed, log to cost-tracker):
+- What Google's Agent2Agent (A2A) protocol is: Agent Cards, task/message model, transport,
+ discovery, auth. Cite the spec/source URLs you actually read.
+- How AbramsEgo could act as an A2A CLIENT so its agents query external A2A-compliant agents
+ for "best method" on a decision (e.g. which affiliate/monetization approach) — the minimal
+ endpoint + client shape, where it'd hook into the existing /api/chat or a new /api/a2a route.
+- Security/gating: A2A means talking to EXTERNAL agents — treat every inbound response as
+ untrusted (it can carry prompt-injection). Spell out the sandbox: no auto-execution of
+ returned instructions, human/officer gate before acting, no secret exposure. Reference the
+ egress-sentinel + the 2026-07-29 stealer lesson.
+
+OUTPUT: write memo to memos/a2a-protocol-scope.md AND a gated go-build copy to
+~/.claude/yolo-queue/pending-approval/a2a-protocol-build-TK-10132.md with:
+- recommended approach + effort estimate (as future build tasks)
+- explicit dependency list (nothing installed yet)
+- a vp-abramsego APPROVE/REVISE/BLOCK block
+Commit `docs(a2a): scope real Agent2Agent protocol integration (gated, TK-10132)`. Print the memo path.
diff --git a/server.js b/server.js
index 9d85d46..ff82c16 100644
--- a/server.js
+++ b/server.js
@@ -302,17 +302,22 @@ async function collectCanaries() {
let verdict = null, scanned = null;
try {
const j = JSON.parse(fs.readFileSync(f, 'utf8'));
- verdict = j.verdict || j.status || (j.down > 0 ? 'DOWN' : j.degraded > 0 ? 'DEGRADED' : (j.up != null ? 'UP' : null));
- // nested shapes: per-unit verdicts (worst-of) or top-level fail/warn/leaking/dead counters
+ verdict = j.verdict || j.status || j.worst_verdict || (j.down > 0 ? 'DOWN' : j.degraded > 0 ? 'DEGRADED' : (j.up != null ? 'UP' : null));
+ // nested shapes: per-unit verdicts (worst-of), top-level counters, or flag-style heartbeats
if (!verdict) {
const worst = (vs) => { const V = vs.filter(Boolean).map(v => String(v).toUpperCase());
- return V.some(v => /FAIL|CRIT|DOWN/.test(v)) ? 'FAIL' : V.some(v => /WARN|DEGRAD/.test(v)) ? 'WARN' : V.length ? 'PASS' : null; };
- if (Array.isArray(j.units)) verdict = worst(j.units.map(u => u.verdict));
- else if ((j.fail > 0) || (j.leaking > 0) || (j.dead > 0)) verdict = 'FAIL';
- else if (j.warn > 0) verdict = 'WARN';
- else if (j.fail === 0 || j.leaking === 0 || j.dead === 0) verdict = 'PASS';
+ return V.some(v => /FAIL|CRIT|DOWN|STALE|DEAD/.test(v)) ? 'FAIL' : V.some(v => /WARN|DEGRAD|EXPIRING/.test(v)) ? 'WARN' : V.length ? 'PASS' : null; };
+ const units = Array.isArray(j.units) ? j.units : Array.isArray(j.results) ? j.results : Array.isArray(j.tokens) ? j.tokens : null;
+ if (units) verdict = worst(units.map(u => u.verdict));
+ if (!verdict) {
+ if ((j.fail > 0) || (j.leaking > 0) || (j.dead > 0) || (j.stale > 0) || (j.config_errors > 0)) verdict = 'FAIL';
+ else if (j.warn > 0) verdict = 'WARN';
+ else if (j.flatCount != null && j.baseline != null) verdict = j.flatCount > j.baseline ? 'WARN' : 'PASS';
+ else if (typeof j.ok === 'boolean') verdict = j.ok ? 'PASS' : 'FAIL';
+ else if (j.fail === 0 || j.leaking === 0 || j.dead === 0 || j.stale === 0) verdict = 'PASS';
+ }
}
- scanned = j.scanned_at || j.checked_at || j.ts || j.at || null;
+ scanned = j.scanned_at || j.checked_at || j.ran_at || j.ts || j.at || null;
} catch (e) {}
const ageMin = Math.round((Date.now() - st.mtimeMs) / 60000);
// heartbeat/last-run time so each canary card can show created date+time
← deefe30 research: candidate affiliate programs w/ verified commissio
·
back to AbramsEgo
·
auto-save: 2026-08-02T01:10:57 (3 files) — build-queue/tasks cf103f8 →