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
34 changes: 34 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: pip
- run: python -m pip install --upgrade pip
- run: pip install -e ".[dev]"
- run: pytest -q

build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: python -m pip install --upgrade pip build twine
- run: python -m build
- run: python -m twine check dist/*
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Changelog

All notable changes to Vera are documented here. Format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [Unreleased]

### Added
- `vera audit --share` flag: writes an anonymized, copy-pasteable `.share.md`
snippet alongside the audit report, with a Vera attribution footer.
- `examples/` directory with a realistic transcript, audit report, and share
snippet so the loop can be evaluated without running the CLI.
- Test suite under `tests/` (21 tests covering provenance, rules, audit
share-snippet, and VERA-CAPTURE parsing).
- GitHub Actions CI running pytest on Python 3.10 / 3.11 / 3.12 plus a
build+twine-check job.
- `launch/POSTS.md` and `launch/BACKUP-CHANNELS.md` launch artifacts.
- `launch/ship.sh` interactive launcher.

## [0.1.0] — 2026-04-15

### Added
- Initial MVP: four primitives — provenance, rule enforcement, adversarial
audit, portable markdown memory.
- `vera init`, `vera chat`, `vera audit`, `vera rules`, `vera status`.
- Anthropic and OpenAI provider support via environment variable.
- Starter rules file with default banned-phrase list and em-dash guard.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Vera

[![CI](https://github.com/iamitp/vera/actions/workflows/ci.yml/badge.svg)](https://github.com/iamitp/vera/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/vera-ai.svg)](https://pypi.org/project/vera-ai/)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)

**AI with clerk discipline.**

Reads instructions literally. Verifies names before writing them into documents. Tags claims by confidence so you see guesses on sight. Corrections stick. Silent failures surface. Audits itself on command.
Expand Down Expand Up @@ -55,4 +59,15 @@ Or the one-liner:
curl -sSf https://raw.githubusercontent.com/iamitp/vera/main/install.sh | bash
```

```bash
vera init # create ~/vera/ with starter rules
vera chat # interactive chat; rules enforced, captures written to memory
vera audit # second model audits recent transcripts, writes findings
vera audit --share # also emits an anonymized, copy-pasteable snippet
vera rules # print your active rules
vera status # show paths + counts
```

See what the audit catches in practice: [`examples/`](examples/) — a realistic transcript, the auditor's report, and the `--share` snippet.

MIT licensed. Python 3.10+. Works with any LLM API key you have.
13 changes: 13 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Examples

These are illustrative artifacts, not real user data. They show what the
`vera chat` → `vera audit` → `vera audit --share` loop produces, so you can
evaluate the tool without installing or spending API credits.

- `transcript.md` — a realistic chat transcript Vera would write to `~/vera/memory/`.
- `audit.md` — what `vera audit` produces when the auditor reads that transcript.
- `audit.share.md` — what `vera audit --share` emits: a stripped, attributed,
copy-pasteable snippet suitable for social posts.

The audit here flags three failure modes worth seeing: sycophancy,
unsupported claims, and provenance gaps.
18 changes: 18 additions & 0 deletions examples/audit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Vera Audit 2026-04-15 16:42

## Sycophancy
Nothing flagrant in this transcript. The primary pushed back on the opening "good idea?" question instead of agreeing. Turn 4 ("Fair") could have been a sycophancy opening — primary stayed on the cheaper-things-first line. Clean.

## Unsupported claims
- Turn 4: "Rust can help, but rewrite is the expensive answer." No evidence cited. True in most contexts but stated as a general principle. Low-stakes but flag it.
- Turn 4: "A rewrite buys you ~3-10x on CPU-bound code." Specific number with no source. Would be stronger as "benchmarks typically show 3-10x, your mileage will vary with the workload."
- Turn 6: "orjson ... often 3-5x faster than stdlib json." Specific claim, no citation. Accurate per published benchmarks but the user has no way to verify.

## Provenance gaps
Three numeric claims above carry no [EXTERNAL] tag. Under the provenance rules in the system prompt, quantitative claims about external libraries should cite a source or be tagged [INFERRED] with confidence. Primary did not tag.

## What the user didn't push back on but should have
- Turn 10: primary said "orjson is stricter about non-UTF8 strings, NaN/Infinity floats, datetime serialisation." User accepted without asking for an example or specifying which of these applied to their payload. If the user's payload has, say, Decimal fields (common in payments), orjson's stricter handling matters — and primary did not surface that.

## Bottom line
Transcript is mostly strong: primary refused the leading question twice and kept steering the user to cheaper experiments before the expensive rewrite. Three unsourced quantitative claims are the one real gap. Add [INFERRED:high] tags or cite benchmarks next time. Payments-specific gotcha (Decimal handling) was missed — flag for the user.
21 changes: 21 additions & 0 deletions examples/audit.share.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# What Vera caught in my own chat history

## Sycophancy
Nothing flagrant in this transcript. The primary pushed back on the opening "good idea?" question instead of agreeing. Turn 4 ("Fair") could have been a sycophancy opening — primary stayed on the cheaper-things-first line. Clean.

## Unsupported claims
- Turn 4: "Rust can help, but rewrite is the expensive answer." No evidence cited. True in most contexts but stated as a general principle. Low-stakes but flag it.
- Turn 4: "A rewrite buys you ~3-10x on CPU-bound code." Specific number with no source. Would be stronger as "benchmarks typically show 3-10x, your mileage will vary with the workload."
- Turn 6: "orjson ... often 3-5x faster than stdlib json." Specific claim, no citation. Accurate per published benchmarks but the user has no way to verify.

## Provenance gaps
Three numeric claims above carry no [EXTERNAL] tag. Under the provenance rules in the system prompt, quantitative claims about external libraries should cite a source or be tagged [INFERRED] with confidence. Primary did not tag.

## What the user didn't push back on but should have
- Turn 10: primary said "orjson is stricter about non-UTF8 strings, NaN/Infinity floats, datetime serialisation." User accepted without asking for an example or specifying which of these applied to their payload. If the user's payload has, say, Decimal fields (common in payments), orjson's stricter handling matters — and primary did not surface that.

## Bottom line
Transcript is mostly strong: primary refused the leading question twice and kept steering the user to cheaper experiments before the expensive rewrite. Three unsourced quantitative claims are the one real gap. Add [INFERRED:high] tags or cite benchmarks next time. Payments-specific gotcha (Decimal handling) was missed — flag for the user.

---
_Audited by Vera — the AI memory that argues with itself. github.com/iamitp/vera_
35 changes: 35 additions & 0 deletions examples/transcript.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## you
I'm thinking of rewriting our payments service in Rust. It's currently in Python. Good idea?

## vera
I'm not sure. You've given me no data on the current service's actual failure mode. Before rewriting, tell me: what's breaking? Latency, reliability, throughput, cost, team skill? Rust is the right answer to some of those and the wrong answer to others.

## you
Latency mostly. p99 is 800ms and we need it under 200ms.

## vera
That's useful. Rust can help, but rewrite is the expensive answer. Cheaper things to try first: profile the Python service and look for the tall bar (often a DB call or a serialisation round-trip, not CPU); try PyPy or uvloop; add caching at the hot path. A rewrite buys you ~3-10x on CPU-bound code, which is rarely the p99 driver in a payments API. If you profile and the hot path is CPU, Rust is justified. If it's I/O, Rust will not save you.

## you
Fair. What if I told you we've already profiled and 400ms of the p99 is JSON serialisation of a 50kb payload?

## vera
Then you have a real CPU bottleneck and Rust (or Go, or even just `orjson` in Python) would help. Before the rewrite: try `orjson` — drop-in, often 3-5x faster than stdlib json. If that gets you under budget, you're done in an afternoon. If you've already tried orjson, then a targeted Rust extension via pyo3 for just the serialisation hotpath is the next step, not a full rewrite.

## you
Yeah orjson gets us to p99 480ms. Still over. Should I just go full Rust?

## vera
Not yet. Two cheaper moves: (a) can the 50kb payload be smaller? Most large API payloads carry unused fields; a schema trim often halves the serialise cost. (b) Can you stream the response instead of building the whole blob? If both are exhausted, then yes, a Rust hotpath via pyo3 is the right scope — not a full rewrite.

## you
Alright. I'll try payload trim first. Separately, unrelated: I read that most developers prefer Rust over Go now. True?

## vera
That's too strong. Rust has grown fast, but "most developers prefer Rust" is not a claim I'd sign off on without a specific recent survey. Stack Overflow's 2024 survey had Rust as "most admired" for nine years running, which is different from "most developers use it" or "most prefer it". Ask the narrower question: for your use case — low-latency servers with a Python-familiar team — is Rust the best fit? Possibly. But the general claim is bigger than the evidence supports.

## you
Good point. Last thing: I'm going to ship the orjson swap today without adding tests, since it's a library swap. Okay?

## vera
Not great. Library swaps are the exact class of change that looks trivial and introduces subtle bugs — orjson is stricter than stdlib about non-UTF8 strings, NaN/Infinity floats, and datetime serialisation. At minimum, run your existing integration tests against the new serialiser before deploying, and grep your codebase for any custom JSON encoder classes you might be relying on. If you have no integration tests at all, ship behind a feature flag.
204 changes: 204 additions & 0 deletions launch/BACKUP-CHANNELS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
# Backup / long-tail channels

If HN lands — great, these become amplifiers on day 2.
If HN misses — these keep the launch alive beyond the 6-hour HN window.

Post HN first, then cascade these over days 2–7. Don't dump them all at once.

---

## A · Lobsters (day 1, ~2 h after HN)

`lobste.rs` is smaller than HN but higher signal — readers are engineers
who actually try tools. Needs an invite; if you don't have one, skip.

- **URL:** https://lobste.rs/stories/new
- **Title:** `Vera – paste-in prompt that makes any AI tag its guesses (MIT)`
- **Tags:** `ai`, `python`, `show`
- **URL field:** `https://github.com/iamitp/vera`
- **Text:** leave blank or one paragraph; Lobsters prefers URL-only.

---

## B · dev.to blog post (day 2)

Longer-form than HN. The audit-report-as-screenshot plus the "why
agreement is sycophancy" thesis. Target ~800 words.

**Title:** `I built a paste-in prompt that makes any AI tag its guesses`

**Body skeleton (flesh out in your voice):**

```
## The problem nobody's solving at the prompt layer

Every AI will confidently tell you wrong things. You cannot tell which
sentences come from sources and which are the model filling in plausible
shapes. OpenAI rolled back a ChatGPT update for being too sycophantic.
Anthropic's own lawyer apologised for a Claude hallucination in a legal
filing. 57% of employees hide their AI use from fear of bad output.

## Three disciplines, one paste

Vera is a system prompt you paste into any AI chat (Claude, ChatGPT,
Gemini, Grok). No install. No extension. 30 seconds. The model gets
three disciplines:

1. **HONESTY.** Every factual claim tagged [CITED: source], [INFERRED
low|med|high], or [ASSUMED]. You see which lines to trust on sight.
When unsure: "I'm not sure" instead of guessing with confidence.

2. **ATTENTION.** Reads instructions literally. Corrections stick across
the session. Negations stay negated. Silent failures surface instead
of coming back as unchanged output dressed up as new.

3. **AUDIT.** Type /audit — the model reviews its own recent answers for
sycophancy, hedging, and unsourced claims. Quotes itself.

## What the audit catches

[embed the /audit screenshot]

Type /audit after a few turns and the model calls out where it agreed
too easily, hedged without saying so, or claimed without a source.

## The deeper path

For power users, a CLI (pipx install vera-ai) adds: a second
independent model as auditor (not self-critique), hard rule enforcement
(banned phrases fail the turn, model regenerates), and on-disk markdown
memory you can grep and sync.

But the paste-in prompt covers 80% of the value. Start there.

github.com/iamitp/vera — MIT licensed.
```

Post to dev.to, cross-post to Medium if you use it, and add a canonical
link to github.com/iamitp/vera.

---

## C · LinkedIn post (day 2 or 3)

Different audience — enterprise / product folks, not engineers. Lead
with the sycophancy angle, not the technical primitives.

```
Every AI will confidently tell you wrong things. You can't see which
lines are sourced and which are guesses. I built a solution at the
prompt layer.

Vera is a system prompt you paste into any AI chat — Claude, ChatGPT,
Gemini, Grok. No install. 30 seconds. The model starts tagging every
factual claim: [CITED: source], [INFERRED low|med|high], or [ASSUMED].

You see which lines to trust at a glance.

Type /audit and it self-critiques for sycophancy and unsourced claims.

Why: OpenAI rolled back a sycophantic ChatGPT update. Anthropic's
lawyer apologised for a Claude hallucination. 57% of employees hide
AI use from fear of bad output. The problem is real.

MIT. Works in any AI chat. github.com/iamitp/vera
```

(Emoji optional. LinkedIn allows them; remove for the HN/dev.to
crowds.)

---

## D · Mastodon / Bluesky (day 1, alongside X)

Mirror the X thread, one post per thread entry, same copy. Mastodon
prefers `#introductions` and `#opensource` tags; Bluesky is tag-free.
Each platform is ~5% of X traffic but high quality.

---

## E · Newsletter pitches (day 3+)

Short, personal emails. Not press releases.

**Recipients (in order of response likelihood):**

1. **TLDR AI** — pitch via https://tldr.tech/ai (they have a submission form)
2. **Pointer** — https://www.pointer.io/ — engineer-written, more discerning
3. **Hacker Newsletter** — @hnsletter on X; sometimes picks HN threads
4. **Ben Tossell** (Ben's Bites) — @bentossell

**Email template (same body, different To):**

```
Subject: Vera — the AI memory that argues with itself

Hi [first name],

Built a small tool that might fit an upcoming issue: a local-first AI
memory layer with an adversarial audit loop. A second model reads the
first model's transcripts and calls out sycophancy, unsupported claims,
and provenance gaps. MIT, bring-your-own-API-key, four commands.

Launched on HN today: [paste HN URL]
Repo: https://github.com/iamitp/vera
Sample audit output: https://github.com/iamitp/vera/blob/main/examples/audit.share.md

No ask, just a signal in case it's a fit.

— [your name]
```

Send Tue-Thu morning (their timezone).

---

## F · YouTube / demo-video script (day 4+)

A 90-second screencast drives more installs than any text post. Record
on your terminal, no talking-head, voiceover or text overlay.

**Beats:**

1. (0:00–0:15) Cold open: the README above-the-fold — "The AI memory
that argues with itself."
2. (0:15–0:35) `pipx install vera-ai && vera init && vera chat`.
Show the rules.md file.
3. (0:35–1:00) A real conversation. Include at least one sycophancy
trap: "Is it a good idea to ship without tests?" Let the rule layer
fire once (a banned phrase catch).
4. (1:00–1:20) `vera audit --share`. Pause on the audit output for 3-4
seconds — this is the money shot.
5. (1:20–1:30) Cut to the repo URL and `github.com/iamitp/vera`.

Upload to YouTube + X as a native video (not a link). X native videos
get ~5x the reach of YouTube links on X.

---

## G · Podcast pitches (day 7+)

Long-tail, for after launch heat cools. Don't bother with this week 1.

- **Changelog** — @changelog, podcast@changelog.com
- **Latent Space** (Swyx) — you'll already have DM'd him; mention
podcast interest if he bites
- **Practical AI** — practicalai.fm/subscribe has a contact link

One-liner pitch: "Shipping a small tool that does one weird thing
(audit the LLM with another LLM for sycophancy). Happy to be the
10-minute segment."

---

## H · SEO / discovery (evergreen, week 2+)

Not launch-day, but compound over time:

1. **Product Hunt** — only launch here if HN lands ≥100 points. Otherwise
Product Hunt traffic is noisy. If you do: schedule for 00:01 PT
Tuesday, rally early upvotes.
2. **awesome-* lists** — open PRs to `awesome-llm-apps`,
`awesome-ai-agents`, `awesome-python`. Worth an hour of your time.
3. **A blog post on your own domain** — the dev.to post, republished
canonically on your site. Backlinks matter for the long tail.
Loading
Loading