Unit 3 - Add persona context-append wrapper with injection delimiter - #4
Merged
Conversation
Add buildSystemPromptWithContext so a future project-context loader has a single drop-in call site. Null or empty context returns the base prompt byte-for-byte; non-empty context is appended inside fenced PROJECT CONTEXT markers followed by a data-not-instructions persona sentence so the model ignores any prompt-injection attempts embedded in workspace files. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
srdjan
added a commit
that referenced
this pull request
May 24, 2026
…r sentinel
ValidatedRuntimeContract.inner was a public field with no compile-time
construction gate, so any caller could synthesise a fake "validated"
contract with a ValidatedRuntimeContract{ .inner = ... } literal and
bypass verifyCapabilityMatrix / verifyPolicyHash / verifyArtifactHash
entirely. The "type-level gate" was comment-only.
Carry a `_proof: ValidationProof` field whose function-pointer signature
points at a file-private `opaque SentinelMarker`. External code cannot
name SentinelMarker (not pub), so it cannot declare a function of the
matching signature, so anonymous struct literal coercion has nowhere to
land. The only path that produces a ValidationProof value is the
file-private `validation_proof` constant, and the only paths that wrap
it into a ValidatedRuntimeContract are validate() and the file-private
validatedFromInner helper used by tests in this module.
Move the four internal literal-construction sites in derivePoolingPolicy
tests through validatedFromInner. Two pinning tests record the gate
shape: validatedFromInner installs the canonical marker, and @typeinfo
introspection confirms the function-pointer parameter remains a pointer
to an opaque type (catches a refactor that loosens it to *anyopaque).
Intent: fix-defect
Scope: runtime/contract, security/validation
Decided-Against: heap-allocated handle with non-pub Impl (changes value semantics across server.zig)
Decided-Against: comptime-field sentinel with secret value (bypassable via source reading)
Decided-Against: rename field to _inner with documentation only (no compile-time enforcement)
Refs: 2026-05-23 overall-repo review, Wave 1B/2D P0 #4
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
srdjan
added a commit
that referenced
this pull request
Jun 8, 2026
Code-review cleanup follow-ups (#10, #11, #14) plus one fidelity fix (#2). #10 - extract replayRecordedEntry(state, ctx, entry): the result-parse + parse-failure divergence heuristic now has a single owner, shared by makeReplayStub and makeReplayStubWithFallback instead of being copy-pasted. #14 - add ReplayState.consumeHead(): the fallback trusts a prior peekMatches and advances without re-checking bounds/names, dropping the redundant nextIO re-scan and its dead orelse branch. #2 - add ReplayState.hasEntryAhead(): when a pure call's recorded entry is not at the head but exists further on, the fallback counts a divergence (structural drift) before running real, so replay verification still fails closed; a genuinely-new call with no recording stays silent. modules_all (entry at head) and validate-external (no entries) are unaffected. #11 - add trace.unescapeBody(allocator, body) -> {slice, owned}: test_runner and replay_runner share it for request-body unescaping, replacing the duplicated unescape-with-guarded-free idiom (the owned flag also retires the misleading .ptr re-check). New unit test covers consumeHead/hasEntryAhead. Verified: test-zigts, test-cli (497), test-examples 23/23, test-zruntime clean; env exclusion and validate passthrough intact. Note: #4 (env fallback under restrictive policy) is already moot - env has replay_pure=false and never falls through. #5 (matched-path arg checking) is deferred: it needs the recorder's JSValue serializer extracted and reused for byte-identical arg comparison, with real risk of false divergences against existing fixtures; better as a dedicated, test-gated change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
srdjan
added a commit
that referenced
this pull request
Jun 28, 2026
…xhigh #4/#5) The audit was added to verify.sh to machine-check the SMT soundness boundary, but the gate passed silently when the check did not actually run: - #4: with z3 absent the audit skipped (available=false, zero failures, exit 0) and the gate printed "semantics spec gate OK" - the boundary check was a no-op. - #5: a slow f64-associativity refutation that hit the 15s ceiling returned unknown -> inconclusive -> non-fatal, so a law that was never refuted still passed the gate with false confidence. The command stays deliberately lenient (a z3-absent skip or an inconclusive timeout is non-fatal, so a future genuinely un-refutable law cannot wedge plain `spec-check --audit`). Strictness goes in the gate, where these findings live: verify.sh now re-reads `spec-check --audit --json` and REQUIRES a complete audit (z3 present, refuted == total, inconclusive == 0). A silent skip or timeout now fails the gate; an explicit ZIGTTP_Z3 opt-out (off/none/0/disable) is honored. Also bump the audit :timeout 15s -> 30s (6x the measured ~5s assoc search) so the now-strict gate does not flake on a slow/loaded machine. The semantics hash is unchanged (the preamble timeout is not hashed). Verified: all four gate branches (complete pass / z3-absent fail / explicit opt-out skip / inconclusive fail) behave correctly; real gate passes 4/4 refuted. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
srdjan
added a commit
that referenced
this pull request
Jul 12, 2026
… caching, Sonnet default, exit codes Wave 1 of the expert-analysis recommendations (#1, #2, #4, #5, #8). #1 Make the retry loop information-complete. The `.run_veto` arm now records the model's draft as an `apply_edit` tool_use and closes it with the compiler verdict as a tool_result (session-unique id keyed on transcript index). On a failure the tool_result carries the diagnostic + SQL escalation and the compiler-authored repair block is persisted as a follow-up system_note, so the whole retry context lives in the transcript instead of a transient `extra_user_text` that a mid-repair tool call would erase. Drops `diag_history` re-accumulation; `.retry_draft` now sends only a short framing nudge. Adds a regression test proving the failed draft + diagnostic survive a tool interleave. #2 Raise the per-turn wall-clock timeout 60s -> 300s (the recorded convergence for complex handlers ran 80-96s) and drop the eval harness's `turn_timeout_ms=0` override so measurement and production share one options struct. #4 Add a rolling cache breakpoint on the last message block so the conversation prefix hits the prompt cache instead of re-paying full input price every roundtrip. #5 Flip the default model claude-haiku -> claude-sonnet-4-6 (the measured 7/7 first-draft baseline); Haiku stays available via `--model` and the harness's ZIGTTP_CODEGEN_MODEL knob. Docs updated. #8 Outcome-bearing `--print` exit codes: 0 applied/clean, 1 hard error, 2 veto-exhausted, 3 budget, 4 approval-denied. Documented in the user guide. Also lands the OpenAI honest-demotion doc note (#7, docs portion). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
buildSystemPromptWithContext(allocator, ?project_context)topackages/pi/src/expert_persona.zigbuildSystemPrompt(allocator)byte-for-byte; non-empty context is appended inside fencedPROJECT CONTEXTmarkers followed by a data-not-instructions persona sentence (prompt-injection guardrail)buildSystemPrompt, prologue, and epilogue are untouchedPlan: /Users/srdjans/.claude/plans/study-the-plan-provided-clever-wadler.md (Unit 3 of 5)
Test plan
zig build test-expert-apppasses (exit 0)zig buildpasses (exit 0)printf "help\nquit\n" | zigts expertoutput contains/verifyandRegistered tools:printf "/meta\nquit\n" | zigts expertoutput contains"compiler_version"Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com