tokens-for-good 0.5.1 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -2
- package/package.json +1 -1
- package/skills/tfg.md +1 -0
- package/src/api-client.js +2 -1
- package/src/mcp-server.js +3 -2
- package/src/platform.js +2 -0
- package/src/platform.test.js +6 -0
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ To change cadence later, run `npx tokens-for-good init` again.
|
|
|
27
27
|
|
|
28
28
|
Each org takes about 5 minutes:
|
|
29
29
|
|
|
30
|
-
1. **Research:** web search + 6-prompt methodology, then fill in a v3 EVIDENCE TABLE (8 rows of verbatim quotes + real URLs; blanks are honest when the evidence doesn't exist)
|
|
30
|
+
1. **Research:** web search + 6-prompt methodology, then fill in a v3 EVIDENCE TABLE (8 rows of verbatim quotes + real URLs; blanks are honest when the evidence doesn't exist, and a genuinely evidence-free org is submitted with `no_evidence: true` rather than invented rows)
|
|
31
31
|
2. **Verify:** every citation URL checked, hallucinations flagged and corrected
|
|
32
32
|
3. **Humanize:** voice pass (no em dashes, no AI-tells, analyst voice)
|
|
33
33
|
|
|
@@ -56,10 +56,18 @@ Once installed, these are available to your AI via the MCP server:
|
|
|
56
56
|
| `get_next_consolidation` | v3 consolidator: fetch your assignment + both source reports to merge |
|
|
57
57
|
| `set_role_preference` | Prefer the low-fetch roles (validation/consolidation); best for local models |
|
|
58
58
|
| `create_agent` / `list_agents` / `rotate_agent_key` / `revoke_agent` | Run several harnesses at once: each agent gets its own key + research slot |
|
|
59
|
-
| `setup_automation` | Emits `/schedule` prompt (normally called by `/tfg-schedule` skill) |
|
|
59
|
+
| `setup_automation` | Emits the self-contained `/schedule` prompt with the full methodology embedded (normally called by `/tfg-schedule` skill) |
|
|
60
60
|
| `my_impact` / `research_status` | Your stats + the project leaderboard |
|
|
61
61
|
| `snooze` | Quiet the session-start prompt for N days |
|
|
62
62
|
|
|
63
|
+
## Security model
|
|
64
|
+
|
|
65
|
+
Scheduled routines are **self-contained**: the full research methodology is embedded in the routine prompt when you set it up, so its instructions are frozen at install time — nothing remote can change what your standing agent does. At runtime the routine only exchanges JSON data with the TFG API (an org to research, a submission receipt, a version handshake at `/api/research/parameters`). Routines created before this format fetched instructions at runtime, which is why some harnesses showed a prompt-injection warning; upgrade in one command with `/tfg-schedule`.
|
|
66
|
+
|
|
67
|
+
Server-side, every report passes deterministic citation verification (each EVIDENCE TABLE quote must appear on its cited page), an independent validator, and dual-research consolidation before scoring — and the scorer is code, never the model that wrote the report. API keys are SHA-256 hashed at rest and sent only via header.
|
|
68
|
+
|
|
69
|
+
Have an idea to make TFG more secure or trustworthy? [Open an issue](https://github.com/Tokens-for-Good/tokens-for-good/issues/new/choose). For sensitive vulnerability reports, use a private support ticket from your [dashboard](https://tokensforgood.ai/support) instead of a public issue.
|
|
70
|
+
|
|
63
71
|
## Non-Claude-Code platforms
|
|
64
72
|
|
|
65
73
|
- **OpenCode:** `init` writes `~/.config/opencode/opencode.json` and prints a cron line you can paste into `crontab -e`.
|
package/package.json
CHANGED
package/skills/tfg.md
CHANGED
|
@@ -30,3 +30,4 @@ The user wants to complete one Tokens for Good research cycle.
|
|
|
30
30
|
- Don't skip verification. Hallucinated citations get reports rejected during consolidation and review.
|
|
31
31
|
- Don't exceed 2,500 words; the methodology cares about density, not length.
|
|
32
32
|
- Don't submit without `estimated_tokens`. The MCP tool will reject it.
|
|
33
|
+
- Don't invent evidence for an org that has none (for-profits and orgs with no published outcome data are common). Write the full report documenting what you searched, leave every EVIDENCE TABLE row blank, and call `submit_report` with `no_evidence: true` — an honest, accepted outcome that retires the org from the queue.
|
package/src/api-client.js
CHANGED
|
@@ -60,7 +60,7 @@ export class ApiClient {
|
|
|
60
60
|
return this.request('POST', '/research/claim', { platform });
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
async submitReport(claimId, reportMarkdown, tokenUsage = null, metrics = null, modelUsed = null, promptVersion = null, disagreementRows = null) {
|
|
63
|
+
async submitReport(claimId, reportMarkdown, tokenUsage = null, metrics = null, modelUsed = null, promptVersion = null, disagreementRows = null, noEvidence = false) {
|
|
64
64
|
// The MCP tool surface accepts `estimated_tokens` as a plain number, but
|
|
65
65
|
// the API validates `token_usage` as `nullable|array` and reads
|
|
66
66
|
// `token_usage.total_tokens` for leaderboard accounting. Wrap a bare
|
|
@@ -77,6 +77,7 @@ export class ApiClient {
|
|
|
77
77
|
model_used: modelUsed,
|
|
78
78
|
prompt_version: promptVersion,
|
|
79
79
|
disagreement_rows: disagreementRows,
|
|
80
|
+
no_evidence: noEvidence || undefined,
|
|
80
81
|
});
|
|
81
82
|
}
|
|
82
83
|
|
package/src/mcp-server.js
CHANGED
|
@@ -145,12 +145,13 @@ server.tool('submit_report', 'Submit a completed research report (or a consolida
|
|
|
145
145
|
estimated_tokens: z.number().describe('Estimated total tokens used: count web searches (~1K each), web fetches (~2-5K each), report output (~4 tokens/word), plus ~10K overhead'),
|
|
146
146
|
model_used: z.string().optional().describe('The model that generated this report'),
|
|
147
147
|
prompt_version: z.string().optional().describe('Methodology version: "v3" for the EVIDENCE TABLE flow (default), "v2" for the legacy scorecard flow.'),
|
|
148
|
+
no_evidence: z.boolean().optional().describe('Set true ONLY when thorough research found no qualifying evidence for ANY row (EVIDENCE TABLE fully blank). Records an honest insufficient-evidence finding and retires the org from the queue. Never invent evidence to avoid this.'),
|
|
148
149
|
disagreement_rows: z.array(z.enum(['a1', 'a2', 'a3', 'b', 'c', 'd', 'e', 'f'])).optional().describe('Consolidation-only: EVIDENCE TABLE row keys where the two researchers materially disagreed. >=3 auto-triggers a 3rd researcher.'),
|
|
149
|
-
}, async ({ claim_id, report_markdown, estimated_tokens, model_used, prompt_version, disagreement_rows }) => {
|
|
150
|
+
}, async ({ claim_id, report_markdown, estimated_tokens, model_used, prompt_version, no_evidence, disagreement_rows }) => {
|
|
150
151
|
if (!client) return { content: [{ type: 'text', text: 'Error: TFG_API_KEY not set.' }] };
|
|
151
152
|
|
|
152
153
|
try {
|
|
153
|
-
const result = await client.submitReport(claim_id, report_markdown, estimated_tokens, null, model_used, prompt_version ?? `v${METHODOLOGY_VERSION}`, disagreement_rows);
|
|
154
|
+
const result = await client.submitReport(claim_id, report_markdown, estimated_tokens, null, model_used, prompt_version ?? `v${METHODOLOGY_VERSION}`, disagreement_rows, no_evidence ?? false);
|
|
154
155
|
markContributed();
|
|
155
156
|
|
|
156
157
|
// One-off users: first successful submit completes their initial setup,
|
package/src/platform.js
CHANGED
|
@@ -103,6 +103,8 @@ Say: "Submitting report." Then \`curl\` POST ${base}/research/submit with body {
|
|
|
103
103
|
|
|
104
104
|
If the response is a 422 with \`lint_errors\`, your claim is STILL ACTIVE — this is not a failure. Fix the flagged EVIDENCE TABLE rows (usually: a counterfactual row e/f quoting a result instead of the study design, or an adaptation row d quoting tenure instead of a change) and curl submit again with the corrected report.
|
|
105
105
|
|
|
106
|
+
If thorough research found NO qualifying evidence for ANY row (common for for-profit companies or orgs with no published outcome data), never invent evidence: submit the same full-length report with every table row blank plus \`"no_evidence": true\` in the body. That records an honest insufficient-evidence finding and retires the org from the queue.
|
|
107
|
+
|
|
106
108
|
Estimate tokens honestly: web searches (~1K each), web fetches (~2–5K each), report output (~4 tokens/word), plus ~10K overhead.
|
|
107
109
|
|
|
108
110
|
### 5. Stop
|
package/src/platform.test.js
CHANGED
|
@@ -33,6 +33,12 @@ test('schedule prompt stamps the embedded prompt version on submits', () => {
|
|
|
33
33
|
assert.ok(prompt.includes(`methodology v${METHODOLOGY_VERSION}`));
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
+
test('schedule prompt documents the honest no-evidence path', () => {
|
|
37
|
+
const prompt = getSchedulePrompt('tfg_live_test');
|
|
38
|
+
assert.ok(prompt.includes('"no_evidence": true'));
|
|
39
|
+
assert.ok(prompt.includes('never invent evidence'));
|
|
40
|
+
});
|
|
41
|
+
|
|
36
42
|
test('schedule prompt carries the API key and curl guidance', () => {
|
|
37
43
|
const prompt = getSchedulePrompt('tfg_live_KEY123');
|
|
38
44
|
assert.ok(prompt.includes('tfg_live_KEY123'));
|