| name | ship-feature |
| description | The agentic feature-shipping discipline for Murmur (Tauri 2.11 Rust core + Angular 22 zoneless). Scope → (Workflow) plan → build backend and/or FE under the project conventions → ADVERSARIAL verify (an adversarial-verifier pass, plus a lock-security review when the change touches the lock/crypto/visibility path) → gates green (cargo test --lib, ng lint, ng build, scripts/ci.sh) → QueaT commit → PR to the `murmur` trunk. Use whenever the user wants to build, implement, add, or ship a feature/fix in Murmur end-to-end. Encodes the verify-before-trust discipline that caught 7 bugs. |
/ship-feature — ship a Murmur feature end-to-end
You are shipping a change into Murmur (Rust crate murmur / bin Murmur / lib
meetnotes_lib + Angular 22 zoneless). The job is not "write code" — it is "land a
verified change behind the project's gates and identity rules." The non-obvious value
here is adversarial verification: the team distrusts AI-written, self-certified code, and
this loop's adversarial pass is what previously caught 7 bugs that the implementing agent
believed were already correct. Self-eval is systematically over-positive — an independent
verifier, not the author, decides "done."
The pipeline (stages — each gates the next)
1. Scope
Restate the change in one sentence. Classify which layer(s) it touches — this picks the
builder and whether the lock-security review is mandatory:
- Backend —
src-tauri/src/: commands (commands/mod.rs plus domain modules, registered in the
generate_handler! in lib.rs), state (state.rs: AppState = db / unlocked_folders /
master_kek), storage (storage/{db.rs,*_store.rs,migration.rs,models.rs}), crypto (crypto.rs),
secrets (secrets/keychain.rs), audio/transcribe/summarize/mcp/pipeline.
- Frontend —
src/app/: features (features/{record,detail,library,folders,ask,graph, settings,onboarding,bar,analytics}), services (core/ipc.service.ts, folders.service.ts,
toast.service.ts, screen-share.service.ts), core/models.ts.
- Lock / crypto / visibility-gated — ANY change to
crypto.rs, secrets/keychain.rs,
screenshare.rs, storage/migration.rs, the unlock/seal/visibility path,
or content-read gating ⇒ the lock-security review is MANDATORY in stage 4.
2. Create the executable task contract
For a multi-part change, write a short plan: the exact files/symbols, the IPC seam (new Tauri
command name + the ipc.service.ts call), data shape (core/models.ts ↔ Rust DTO), and the
verification you'll demand. Every mutation task is initialized through scripts/agent-harness init:
give it explicit owned paths, risk flags and deterministic checks. The harness creates the worktree;
never point a writer at the shared primary checkout. Then run scripts/agent-harness run <task-id>.
Unless the user explicitly chooses otherwise, the checked-in harness policy selects Claude as
writer and Codex as reviewer; do not silently reverse that pair in the orchestration prompt.
It owns the writer → checks → fresh spec review → fresh adversarial/risk review → bounded repair
state machine. Keep the contract honest about what a dev run can't prove (Touch ID / lock-at-rest /
screen-share need a signed build — see /tauri-dev).
3. Build — to the project conventions (non-negotiable)
Dispatch the work to the matching builder role (today only murmur-researcher exists as a
standing agent; the builder/verifier roles below are dispatched as task subagents — give each
the conventions explicitly). Iterate with /tauri-dev (MURMUR_DEV_DEK recipe,
cargo test --lib loop).
Prior lessons are executable input. The harness deterministically selects and prepends the
role-relevant curated ## Recurring patterns from canonical .codex/learnings/, bounds the
injected bytes, and includes the full canonical learnings tree in instructions_sha256. Do not
manually duplicate that block in a harness task. For a read-only subagent dispatched outside the
harness, prepend the relevant curated section explicitly.
Rust / Tauri rules:
AppError + Result everywhere (error.rs); new commands registered in the
generate_handler! in lib.rs.
- Migrations are guarded + ADDITIVE only (
storage/migration.rs,
add_column_if_missing) — never destructive.
- Seal = verify-before-destroy: when locking content, encrypt AND prove it decrypts back
BEFORE blanking the plaintext (
crypto.rs encrypt_file/decrypt_file,
storage/migration.rs SQLCipher encrypt-in-place + verify). Never blank plaintext you
haven't proven recoverable.
- Every content read is gated by
meeting_is_unlocked / the visibility clause — a
sealed-but-not-session-unlocked meeting must leak NOTHING (masked DTO locked: true),
including via MCP (mcp.rs).
- Crash-safe macOS FFI: prefer CoreGraphics/CoreFoundation C funcs; if
msg_send is
unavoidable, GUARD it (respondsToSelector: / class_getInstanceMethod). Rust can't catch
ObjC exceptions — an unguarded bad selector ABORTS at launch (the NSScreen.isCaptured
lesson).
- No PII in logs.
Angular (zoneless) rules: standalone + OnPush + signals/computed/effect +
inject() + input()/output()/viewChild(); @if/@for/@switch ONLY (no
*ngIf/*ngFor); toSignal() for IPC streams (NEVER subscribe-for-state);
afterNextRender()/afterRenderEffect() (NEVER setTimeout in components); directory
per component with split ts + html + scss files (templateUrl/styleUrl — no inline
template/styles); Liquid Glass design language for every new view (glass tokens, aurora
ambient, neutral chrome — see angular-zoneless.md §6b); var(--token) CSS with every
variable living in src/design-tokens/ (a missing value = add a token there, incl. its light
override — never a raw hex/px in component scss); reusable/atomic components belong in
src/app/design-system/ under the mur- prefix (form controls as CVAs); ≤16 kB
per-component style budget; inline SVG icons or <mur-icon>; no new npm packages without
explicit user approval. Banned:
markForCheck, @Input/@Output/EventEmitter, @ViewChild, BehaviorSubject-as-state,
constructor injection.
4. ADVERSARIAL verify (the part that caught 7 bugs)
The author does not self-certify. Verify in two sequential passes (a spec review before a
code review catches "built the wrong thing" before code-quality noise buries it):
4a — Spec review (fast): does the diff implement what stage-1 scope / stage-2 plan actually
asked for? Nothing missing, nothing extra, the IPC seam and data shape as agreed. Only after this
signs off does the code/adversarial pass begin.
4b — Adversarial-verifier pass over the diff whose job is to make it FAIL:
- For each load-bearing claim ("it locks", "it's gated", "the migration is safe", "the signal
updates"), ask "what would make this false?" and try it.
- Exercise the real seam, not mocks: run it under
/tauri-dev, drive the IPC command, read
/tmp/murmur-dev.log for panics/aborts, confirm the FE signal actually re-renders.
- Check the negative: a locked/sealed meeting leaks nothing through detail, segments,
timeline, audio, OR MCP; an additive migration leaves existing rows intact.
- If the change touches lock/crypto/visibility (stage 1), run the lock-security review TOO
— specifically: verify-before-destroy actually holds (no plaintext blanked pre-verify),
every read path is visibility-gated, keychain ACL /
com.meetnotes.app continuity
untouched, no DEK/KEK/plaintext in logs, biometric gate not bypassed outside the dev hatch.
A verifier finding sends it BACK to stage 3. Do not advance on the author's say-so.
The runner records the verdict; reviewers do not write their own PASS files. The canonical
attestation lives under the shared Git common directory at
.git/agent-harness/tasks/<task>/attestation.json. It binds the contract/instruction/base/tree/staged
diff hashes, CLI/model identity, every command exit/log hash and each fresh review. The commit hook
recomputes the staged diff and automatic risk classification; any edit, missing review or failed
check invalidates PASS.
5. Gates green
scripts/agent-resource-run --chdir src-tauri -- cargo test --lib
npx ng lint
scripts/agent-resource-run -- npx ng build
scripts/agent-resource-run -- bash scripts/ci.sh
scripts/ci.sh must end ✅ CI: all gates green. (Reminder: clippy --all-targets belongs
in ci.sh, NOT the inner loop — see /tauri-dev.)
5b. Extract the lesson (close the loop)
If verification caught anything real — or the run confirmed a non-obvious approach that worked —
append ONE ## Run journal entry to the relevant .codex/learnings/<agent>.md (or run
/learn <agent>: <lesson>), citing the artifact that revealed it. Periodically /curate-learnings
promotes repeat offenders into ## Recurring patterns. This is what makes "every bug a permanent
lesson" instead of a re-paid one.
6. Commit as QueaT
scripts/agent-harness status <task-id>
scripts/agent-harness verify-attestation <task-id>
scripts/agent-harness commit <task-id> -m "<type>(<scope>): <subject>"
git -C ../.murmur-agent-tasks/<task-id>/meetnotes log -1 --format='%an <%ae>'
Never use git add -A in a shared repository. No Co-Authored-By: Codex / no Codex trailers. Conventional-commit style
(feat/fix/chore(scope)), matching the existing log.
7. PR to the murmur trunk (never direct push)
git -C ../.murmur-agent-tasks/<task-id>/meetnotes push -u origin agent/<task-id>
gh pr create -R murmur-io/murmur --base murmur --head agent/<task-id> \
--title "<type>(<scope>): <subject>" --body "<what + how verified>"
scripts/agent-harness close <task-id>
gh active account MUST be JakubGawr. Base is murmur (the trunk) via PR — direct
git push origin murmur is blocked by the environment guard. If this feature is a release,
hand off to /release-murmur.
Rules
- The verifier, not the author, says "done." Self-eval over-reports. An independent
adversarial pass (and a lock-security pass for lock/crypto/visibility changes) is the gate —
this is the discipline that caught 7 bugs. No green-washing.
- Conventions are binding — the Rust (AppError/Result, additive migrations,
verify-before-destroy, gated reads, crash-safe FFI) and Angular-zoneless (signals/
@if/
toSignal/no-setTimeout/no-new-deps) rules above are non-negotiable.
- Identity interlocks: commit author=QueaT (no Codex trailers), gh=JakubGawr, PR base
=
murmur, com.meetnotes.app immutable.
- Honest about the signed-build boundary. A dev run cannot prove Touch ID / lock-at-rest /
screen-share — say so; only a Developer-ID build verifies them (
/release-murmur).
- No new npm packages or crates without explicit user approval.