Skip to content

v0.18.0 — adoption metrics (P4) + AcmeAds vertical demo (P5)

Choose a tag to compare

@hanfour hanfour released this 03 Jun 05:55
· 75 commits to main since this release

Why

Two priorities-plan strands ship together:

  • P4 — adoption metrics. pmk adoption answers "is anyone actually using this?" from local signals (run markers, atom telemetry, audit window), so the kit's value can be judged from data instead of vibes.
  • P5 — AcmeAds vertical demo. A self-contained way to watch the knowledge loop work end-to-end on a fictional ad-tech workspace, rather than reasoning about it abstractly: seed atoms (P5a) → pmk demo run driver (P5b) → a ~15-min walkthrough doc (P5c).

What shipped

  • pmk adoption — pure report over audit + telemetry + corpus + ~/.pmk/adoption.json markers; five clamped metrics.
  • pmk demo seed|unseed — five approved AcmeAds atoms (placements, vCPM, customer migration, finance terms, onboarding dedup), tagged acme-ads-demo, idempotent.
  • pmk demo run — posts the five guided questions as a real user (PMK_DEMO_USER_TOKEN, chat:write only), correlates each turn.processed, prints a Q→A transcript. Reply-readback uses the gateway bot token's conversations.replies (bot replies are always threaded). --dm / zero-config DM auto-open (uses im:history); --channel for a channel (needs channels:history); --dry-run previews.
  • AcmeAds demo walkthrough (examples/acme-ads-demo.md) — leads with the zero-credential manual DM path.

Fixed

  • Demo readReply no longer silently swallows conversations.replies errors — a missing bot scope now surfaces in the transcript (e.g. missing_scope for channels:history) instead of a generic "did not stabilise".

Dogfood notes (honest)

The knowledge loop was verified live end-to-end: a pmk demo run against the seeded corpus produced five turn.processed events with the correct atoms injected, the right audience tier, and the Q5 escalation boundary (hadMraAsk), with grounded answers (e.g. the vCPM formula sourced from placement_daily).

The smoke also surfaced two host-side, non-code issues worth recording:

  1. Socket throttling. A backgrounded gateway daemon (nohup … & disown) got App-Nap/sleep-throttled on macOS, starving Slack's Socket-Mode ping/pong (5s window) → the socket reconnected endlessly but never stayed healthy → a silent multi-day outage with the process alive and the heartbeat ticking. Fix: run under caffeinate -dimsu. (Hardening follow-up: the gateway's built-in caffeinate -i -t 300 is too weak.)
  2. Transcript-capture depends on Slack config. Automated reply-readback needs the bot's im:history (DMs) or channels:history (channels), and depends on Slack delivering the demo user's messages. The loop itself is independently verified via turn.processed; the transcript convenience is gated on the operator's app scopes — now reported honestly.

Test plan

  • @pmk/cli: 483 tests, 100% pass (npm --workspace packages/cli test).
  • Live: seeded AcmeAds corpus, ran the five-question demo against the host daemon, confirmed five grounded turn.processed turns + Q5 escalation.