Files
meshcore-analyzer/qa
d14317b008 fix(qa): query blacklist retention by from_pubkey (#2069)
## Summary

- query `transmissions.from_pubkey`, the column present in CoreScope's
real schema, instead of the nonexistent `from_node`
- preserve the existing SQLite parameter binding and stdin transport
- derive the unit-test table from the ingestor's committed `CREATE
TABLE` definition rather than a hand-written schema
- add positive, negative, case-normalization, injection-shaped input and
missing-column coverage
- verify the query against the committed staging-captured E2E fixture

## Why

The parameter-binding change correctly removed SQL interpolation, but
its count query and test fixture both used `from_node`. The production
schema defines `transmissions.from_pubkey`; therefore the live QA probe
could only fail with `no such column: from_node`, while the synthetic
unit fixture remained green.

The ingestor stores attributed ADVERT pubkeys as lowercase hex. The
query now uses:

```sql
SELECT COUNT(*)
FROM transmissions
WHERE from_pubkey = lower(:pubkey);
```

The value remains a bound parameter. No production schema or runtime
code changes.

## Verification

- `bash -n qa/scripts/blacklist-test.sh`
- `bash -n qa/scripts/test-blacklist-sql.sh`
- `bash qa/scripts/test-blacklist-sql.sh` — 72 passed, 0 failed
- schema fixture extracted directly from `cmd/ingestor/db.go`
- committed E2E fixture returns the same attributed-row count through
the helper query and a direct control query
- legacy fixture containing only `from_node` fails non-zero with `no
such column: from_pubkey`
- injection-shaped, empty, whitespace, multibyte and long values remain
literal bound values
- `git diff --check`

This PR intentionally contains only the schema correction and its
regression coverage.

Co-authored-by: Openclaw <openclaw@Openclaws-Mac-mini.local>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 17:32:54 +02:00
..

CoreScope QA artifacts

Project-specific assets for the qa-suite skill.

Layout

qa/
├── README.md                  ← this file
├── plans/
│   └── <release>.md           ← per-release test plans (one file per RC)
└── scripts/
    └── api-contract-diff.sh   ← CoreScope-tuned API contract diff

How to run

qa staging              # use the latest plans/v*-rc.md against staging
qa pr 806               # use plans/pr-806.md if it exists, else latest plans/v*-rc.md
qa v3.6.0-rc            # use plans/v3.6.0-rc.md

The parent agent loads the qa-suite skill, which reads:

  1. The plan file from qa/plans/
  2. Bundled scripts from qa/scripts/
  3. The reusable engine + qa-engineer persona from the skill itself

Adding a new plan

For each release candidate, copy the latest plans/v*-rc.md to plans/<new-tag>.md and update:

  • The commit-range header (vN.M..master)
  • Any new sections for new features in the release
  • The "Test data" section if new fixture types are needed
  • The GO criteria (which sections are blockers)

Adding a new script

Custom scripts go in qa/scripts/ with mode=auto: <script-name> referenced from the plan. The qa-engineer subagent runs them with two args: BASELINE_URL TARGET_URL.

Authoring rules from the qa-suite skill:

  • 4-way error classification: curl-failed / parse-empty / shape-diff / field-missing
  • Distinguish HTTP errors from jq parse failures
  • Don't silence stderr — script bugs must surface
  • Exit code = number of failures