Skip to content

Populate prawduct ai-content prompts (open-queue #2 post-#139)#200

Merged
Jason-Vaughan merged 2 commits into
mainfrom
feat/prawduct-aicontent-prompts
May 22, 2026
Merged

Populate prawduct ai-content prompts (open-queue #2 post-#139)#200
Jason-Vaughan merged 2 commits into
mainfrom
feat/prawduct-aicontent-prompts

Conversation

@Jason-Vaughan
Copy link
Copy Markdown
Owner

@Jason-Vaughan Jason-Vaughan commented May 21, 2026

What

Replaces the three placeholder prompts in data/templates/prawduct/template.json with real content. The three steps (changelog-update, learnings-capture, memory-update) shipped with empty prompt: "" strings post-Chunk-11c and surfaced as skipped rows in every V2 wrap drawer — functional, but produced no user-visible session output.

Why

Highest-leverage open-queue item per MEMORY.md boot pointer: gives V2 prawduct wraps actual CHANGELOG entries, learnings-capture, and memory-update output instead of three SKIPPED rows. The plumbing has been in place since Chunk 5 (real ai-content handler with send/poll/capture/validate); only the prompts were missing.

Validated end-to-end this morning via the V2 smoke test on prawduct-test (commits 1841083 + 9e1d79e3) — confirmed the three SKIPPED rows render correctly but produce no useful output. That gap closes here.

How

Prompt design principles:

  • AI does the gathering. Prompts instruct the AI to run git log, git diff, read CHANGELOG.md / MEMORY.md / learnings.md itself, rather than depending on TC-side prompt-interpolation expansion. Matches the ADR 0002 hybrid contract ("TC owns workflow; AI owns content"). Keeps the Chunk 5 interpolation surface unchanged (only {previousMemoryBlock} is recognized; this PR pins no-new-tokens via a test).
  • memory-update is the structured one. captureFields: ["summary", "nextSteps", "learnings"] requires the AI to emit three ## Heading blocks (case-insensitive match per _parseFields). Prompt explicitly names each heading + explains WHY (so future methodology authors don't strip the structured-response section as verbose).
  • Two free-form steps have ## Result tail discipline. changelog-update and learnings-capture have no captureFields, so the handler's ≥20-char threshold is the only validation. The ## Result heading convention gives the wrap commit body something stable to summarize and prevents AI no-ops from accidentally passing the threshold with chatter.
  • Honest no-op exit. Both free-form prompts include explicit "if there's nothing real this session, say so" guidance rather than nudging the AI to fabricate signal. Important for routine sessions.

Migration note for existing prawduct projects

The methodology template is cached at ~/.tangleclaw/templates/prawduct/template.json (via _copyBundledTemplates at lib/store.js on TC server boot). _reconcileMergeBy:id (ADR 0001) is additive-only on existing step ids, so cached templates with prompt: "" keep their empty prompts on every subsequent boot.

To pick up the populated prompts on an existing install:

  1. Stop the TC server.
  2. Delete ~/.tangleclaw/templates/prawduct/template.json (or the full ~/.tangleclaw/templates/prawduct/ directory).
  3. Restart TC. _copyBundledTemplates re-copies from data/templates/prawduct/template.json only when the cached dir is missing.

The per-project .tangleclaw/project.json is the per-project config, not the methodology template cache — deleting it does not refresh the bundled prompts. (Earlier draft of this PR pointed at the wrong file; Critic m1 caught it pre-merge.)

Alternative: wait for a future chunk that introduces per-field reconciliation of step.prompt. Tracked in .claude/plans/prawduct-aicontent-prompts.md Chunk 1 "Out of scope".

Test plan

  • 9 new tests in test/prawduct-aicontent-prompts.test.js:

    • changelog-update prompt ≥200 chars, references CHANGELOG.md / [Unreleased] / ## Result.
    • learnings-capture prompt ≥200 chars, references learnings.md / ## Result.
    • memory-update prompt ≥200 chars, mentions ## Summary / ## NextSteps / ## Learnings; captureFields lockstep.
    • Cross-cutting: every prawduct ai-content step has captureFields or ## Result tail discipline.
    • Lockstep drift guard (post-Critic): every captureField appears as ## <Field> literal in the prompt.
    • Inverse drift guard (post-Critic): every ## <Heading> in the prompt (other than ## Result) corresponds to a captureField.
    • No {...} interpolation tokens (post-Critic): pins the no-new-tokens decision.
    • _reconcileMergeBy additive-only behavior pin (post-Critic): unit test that grounds the migration note's claim.
    • Minimal-methodology empty-prompt anchor: pins that minimal's ai-content steps still ship empty so Chunk 11c contract remains exercised.
  • Full suite: 2285 / 2285 pass on this branch (was 2276 on main post-Fix tmux.createSession env vars not reaching launch command process #191; net +9).

  • Independent Critic review: YELLOW → GREEN. 1 MINOR (m1: migration recipe) + 5 NITs + 4 coverage gaps. m1 + n2 (Chunk-9 leak) + n5 (ADR Status-line chronology) + all 4 coverage-gap pins addressed in fixup commit 209ccfb. n1 (_parseFields whitespace fragility) filed as follow-up enhancement (out of scope per build plan — no handler code changes). n3 (cross-step ## Result heading is currently safe per Critic's own assessment), n4 (em-dash diff noise, cosmetic) declined.

Files touched

  • data/templates/prawduct/template.json — three ai-content step prompts populated
  • docs/adr/0002-wrap-pipeline-contract.md — Status line extension marker (post-Critic: chronologically ordered)
  • CHANGELOG.md[Unreleased] ### Changed entry with corrected migration note
  • test/prawduct-aicontent-prompts.test.js — new (9 tests, 3 describe blocks)

Out of scope

  • New interpolation tokens ({recentCommits}, {filesChanged}, {lastWrapSha}). Tracked in .claude/plans/prawduct-aicontent-prompts.md Chunk 1 "Out of scope".
  • Per-field reconciliation of step.prompt for existing projects. Same.
  • End-to-end smoke test of new prompts on a real prawduct session. Planned as Chunk 2 in the same plan file (post-merge).
  • _parseFields whitespace tolerance on heading names (Critic n1 — file as follow-up enhancement).

Replaces the three placeholder prompts in
data/templates/prawduct/template.json that surfaced as `skipped` rows in
every V2 wrap drawer post-Chunk-11c. Real prompts now instruct the AI to:

- changelog-update: edit CHANGELOG.md [Unreleased] per Keep-a-Changelog
  style with a `## Result` tail acknowledgment.
- learnings-capture: append non-obvious takeaways to
  .tangleclaw/memories/learnings.md (or write `no novel learnings` rather
  than fabricating signal).
- memory-update: write a new `Last Session` block to MEMORY.md (demoting
  the prior block to wrap-log.md) and emit `## Summary` + `## NextSteps`
  + `## Learnings` heading blocks. `_parseFields` in
  lib/wrap-steps/ai-content.js parses these against the step's
  captureFields and `_completeV2Wrap`'s summary deriver consumes
  `## Summary` for the wrap commit subject.

ADR 0002 Status line extended with the prompt-population marker.
CHANGELOG.md [Unreleased] under `### Changed` gains an entry plus the
migration note for existing prawduct projects (_reconcileMergeBy:id is
additive-only per ADR 0001 — they keep empty prompts on reconcile until
a future per-field reconciler chunk).

Tests: new test/prawduct-aicontent-prompts.test.js pins prompt
invariants (>=200 chars each, `## Summary` / `## NextSteps` /
`## Learnings` instructions in memory-update, captureFields lockstep)
and the minimal-methodology empty-prompt anchor (Chunk 11c contract
still exercised by a bundled methodology).

Full suite: 2281/2281 pass (+5 from new structural pins).
@Jason-Vaughan Jason-Vaughan added the enhancement New feature or request label May 21, 2026
m1 (MINOR — load-bearing): CHANGELOG migration recipe pointed at the
per-project `.tangleclaw/project.json` instead of the methodology
template cache `~/.tangleclaw/templates/prawduct/template.json`.
Deleting the per-project config does not refresh the cached template;
`_copyBundledTemplates` only re-copies from `data/templates/` when the
cached directory is missing. Corrected the migration paragraph to spell
out the cache location, the stop-server prerequisite, and the
copy-on-empty contract.

n2 (NIT): `learnings-capture` prompt referenced `Chunk 9` by name in
its step-5 instruction. Internal #139 sequence numbering leaks no
meaning to a future runtime AI. Removed the parenthetical; sentence is
unchanged in content.

n5 (NIT): ADR 0002 Status-line extension marker for this chunk was
inserted out of chronological order (was: 2026-05-14 ... 2026-05-21
... 2026-05-15 ... 2026-05-18). Restored to chronological order at the
end of the chain (after Chunk 10).

Coverage gaps (4 new pins in test/prawduct-aicontent-prompts.test.js):

- Lockstep: every captureField on memory-update appears as a
  `## Heading` literal in the prompt. Catches a future PR that adds
  `risks` to captureFields without adding `## Risks` to the prompt
  (would silently block every wrap).

- Inverse drift: every `## Heading` in the prompt (other than the
  free-form `## Result` tail) corresponds to a captureField. Catches
  the symmetric case — a `## Risks` block instructed but never declared
  to the parser.

- No `{...}` interpolation tokens: pins the build-plan's explicit
  out-of-scope decision (no new tokens). Prevents accidental
  introduction of `{recentCommits}` etc. that `_interpolatePrompt`
  would pass through verbatim.

- `_reconcileMergeBy` additive-only behavior pin: simulates an existing
  on-disk template with empty prompts, calls `store._reconcileMergeBy`,
  asserts `null` (no change). Grounds the CHANGELOG migration note's
  behavioral claim with a unit test.

Full suite: 2285 / 2285 pass (+9 from this chunk total).
@Jason-Vaughan Jason-Vaughan merged commit f552ec3 into main May 22, 2026
@Jason-Vaughan Jason-Vaughan deleted the feat/prawduct-aicontent-prompts branch May 22, 2026 03:35
Jason-Vaughan added a commit that referenced this pull request May 23, 2026
Eats its own dogfood: invokes the new `lib/wrap-steps/version-bump.js`
handler (shipped in PR #202 a few hours ago) programmatically against
this repo, then flushes the two staged writes via the same
`commit._flushStagedWrites` the V2 wrap pipeline would use.

Handler output:

  - oldVersion: 3.16.2
  - newVersion: 3.17.0
  - bumpLevel: minor (subsections: Changed, Fixed, Added)
  - detail: 3.16.2 → 3.17.0 (minor)

Highlights of this release (full notes in CHANGELOG.md):

- **#139 Methodology-aware single-button session wrap (series closed).**
  12 chunks across the May 14–19 window. `wrapV2: true` is now the
  default. Full server-side pipeline (`pr-check` → `critic-check` →
  `version-bump` → `ai-content` × 3 → `priming-roll` → `commit`)
  replaces the legacy NL-prompt-via-tmux flow. ADR 0002 is the
  durable home.

- **Open-queue #2 (PR #200): prawduct ai-content prompts populated.**
  Three placeholder steps (`changelog-update` / `learnings-capture` /
  `memory-update`) gain real prompts. V2 wraps now produce CHANGELOG
  entries / `learnings.md` entries / MEMORY.md session blocks
  instead of three SKIPPED rows.

- **Open-queue #3 (PR #202): real version-bump handler.** The handler
  that cut THIS release. Last #139-era no-op stub replaced.

- **PR #191: tmux env-ordering hotfix.** Engine `launch.env` now
  reaches the spawned engine process (was silently dropped pre-fix).
  Surfaced via Aider / LiteLLM `OPENAI_API_KEY` integration.

- **#168 CHANGELOG structural-invariants test.** Pinned post-PR #166
  regression class.

CHANGELOG `[Unreleased]` heading retained at the top with an empty
body (per the handler's promote contract) so the next session has
somewhere to accumulate entries.

Banner emoji NOT auto-injected — to be added manually as `> 🚀` (this
is a feature release, not a bug-fix) in a follow-on commit or
release-notes edit per the project's banner convention.

The UTC-vs-local-date bug in the version-bump handler (surfaced
cutting this release: handler stamped 2026-05-23 in UTC; manually
patched to 2026-05-22 to match the local-zoned convention used by
every prior CHANGELOG entry) is filed as #205. Future releases pick
up the fix when that lands.
Jason-Vaughan added a commit that referenced this pull request May 23, 2026
`lib/wrap-steps/ai-content.js:_parseFields` previously required exact-
string equality (after `.toLowerCase()`) between `## Heading` text and
the declared `captureField` name. This silently rejected natural
Markdown a human or AI would write — `## Next Steps` vs
`captureFields: ['nextSteps']` — and halted the wrap pipeline with
"Required captureField missing." Surfaced as Critic n1 on PR #200.

- lib/wrap-steps/ai-content.js: new `_normalizeFieldKey(s)` helper —
  lowercase + strip every non-`[a-z0-9]` — applied symmetrically to
  both sides of the heading-vs-captureField comparison. Output map
  keys remain the DECLARED captureField name (camelCase), not the
  normalized form, so downstream consumers (the summary deriver in
  `lib/sessions.js:_completeV2Wrap`, the prawduct lockstep pins) need
  no changes.
- test/wrap-pipeline.test.js: 11 new tests — natural-English
  variants (space, kebab, screaming snake, dotted), canonical form
  still matches (regression pin against over-correction), mixed-
  style multi-heading, output-key contract, plus a dedicated
  `_normalizeFieldKey` describe (stripping, case folding, digit
  preservation, defensive coercion).
- CHANGELOG.md: `### Fixed` entry under `[Unreleased]`.

Prawduct lockstep + inverse-drift tests in
`test/prawduct-aicontent-prompts.test.js` are intentionally left
untouched — they enforce a STRICTER convention (single-word
PascalCase headings) than the parser, as a style guide for bundled
methodology prompts. The looser parser is the safety net for
community-authored methodologies and for AI responses that drift
from canonical.

Normalization is a strict superset of the prior equality contract:
every input the old parser matched still matches; only the
previously-rejected variants now also match.

Critic verdict GREEN — no MAJORs, no MINORs.

Full suite 2360/2360 (net +11 from this fix).

Closes #201.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant