Repository navigation
feat(prompts): overridable Prompts interface (Layer 0) - #62
Merged
Merged
Conversation
…r 0) Open the 4 load-bearing compression rules for host override behind an acknowledgeRisk gate, so prompts can be customized without forking the kernel. Pure additive: defaults are byte-identical and renderNudgeText stays one-arg backward-compatible. - src/prompts.ts: Prompts interface, defaultPrompts, resolvePrompts - src/nudge-text.ts: renderNudgeText(decision, prompts=defaultPrompts) - src/index.ts: export defaultPrompts/resolvePrompts/Prompts - DESIGN-prompts.md: layer 0-3 roadmap + load-bearing/surface split - tests/prompts.test.ts: 11 tests (defaults, gate, override flow)
ranxianglei
force-pushed
the
2026-08-12_prompts-interface
branch
from
August 12, 2026 17:19
f56b90a to
45c3421
Compare
…ew R1/R2) Regression review (PR #62) found two correctness gaps: R1: resolvePrompts spread overrides verbatim, so an explicit {field: undefined} or {field: null} clobbered a good default with undefined/null (then embedded "undefined"/"null" into the prompt). Now only string-valued overrides take effect; undefined/null/wrong-type are dropped before the gate and the merge, so a malformed partial never degrades the canonical rules and never triggers a false throw. R2: defaultPrompts was a mutable singleton. A buggy caller mutating one field would corrupt every other consumer. Now Object.freeze'd. Tests: +9 (tier-3 custom text, non-clobber for undefined/null/number, no-false-throw, no aliasing/mutation of defaults, frozen assertion, two-arg-vs-one-arg byte-identity across all 4 modes, full-rule verbatim embedding). 235 -> 244 pass.
Merged
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.
What
Opens the kernel's 4 load-bearing compression rules for host override, behind an
acknowledgeRiskgate — the foundation for customizable prompts across acp-kernel and its downstreams (billion-context-pi, opencode-acp, …). Tracks dog/billion-context-pi#27 (design discussion → approved → reviewed).Pure additive: default wording is byte-identical, and
renderNudgeTextstays one-arg backward-compatible. No downstream change required to keep current behavior.Why staged this way
Prompt text is split into load-bearing (the compression rules — tuned over months, quality-critical for retrieval) vs surface (headers, chrome, descriptions). Layer 0 opens only the load-bearing rules, gated so overrides can't happen by accident. Full rationale + the 4-layer roadmap (override interface → prompt-set format → adapter plumbing → third-party packs) is in
DESIGN-prompts.md.Changes (5 files, +451/−11)
src/prompts.ts(new) — the public override surface:interface Prompts { compressPhilosophy; howToCompressRules; tier2DistillRules; tier3CondenseRules: string }defaultPrompts—Object.freezed singleton (review R2: callers can't corrupt the shared default).resolvePrompts(overrides?, { acknowledgeRisk? })— non-string values are dropped (review R1:{compressPhilosophy: undefined}no longer clobbers the good default); throws on any override without acknowledgement, naming the offending keys. Mirrors the existingcompress-tooldangerous/acknowledgeRiskpattern.src/nudge-text.ts—renderNudgeText(decision, prompts = defaultPrompts); an override now flows into every nudge tier (gentle / emergency / tier-2 / tier-3).EFFICIENCY_NOTE/EMERGENCY_HEADERbecame helper functions ofprompts.src/index.ts— exportdefaultPrompts,resolvePrompts,Prompts,ResolvePromptsOptions.tests/prompts.test.ts(new, 20 tests) — defaults mirror the verbatim constants; empty override no-op; override without ack throws + lists keys; override with ack merges;renderNudgeTextreflects custom text across all four modes; non-clobber (undefined/null/numberdropped); no-aliasing/mutation; frozen assertion; one-arg vs two-arg byte-identity.DESIGN-prompts.md(new) — load-bearing/surface classification, host usage, non-goals, Layers 1–3 design intent, risk table.Verification
npm run typecheck✅npm test✅ — 244 pass / 0 fail (224 baseline + 20 new)npm run build✅ —dist/index.js+.d.tsemit the new exportsDual-agent review
Two oracle agents reviewed for regressions (per issue #27). Verdict: ship-with-fixes. Two real issues found and fixed (R1 non-string clobber, R2 mutable singleton — both above). Non-blocking observations documented in
DESIGN-prompts.md.Publishing
Rebased onto current master (v0.0.20,
13a345e). Note: 0.0.21 already shipped for an unrelated nudge fix (#64) and does NOT include Layer 0. When this PR merges, Layer 0 lands in the next publish (0.0.22). Downstream billion-context-pi#128 is blocked on that.Non-goals (deliberately deferred)
Surface text (summary header, status-report headers, tool descriptions) and inline validation errors stay fixed for now — see
DESIGN-prompts.md §Non-goals. NoConfig/defaultConfigchange; the host holds the resolvedPromptsobject and passes it explicitly.🤖 Merge is human-only — I will not merge this PR.