A lens has one charter, the one this pipeline ships; what a repository knows that is not general to the lens - its platform and layers, the record it keeps its decisions in, what its users already have, the calibration entries that are its own - goes in a file the config names for the lens (lenses.<name>.section), and Charter appends it after one blank line. The charter sha in every reuse key covers the combined text. The config refuses a path outside the repository - absolute, or climbing out with `..` - by the check slots.dir had, now one both settings share; a file missing or one the run could not use (a dangling link, unreadable, not UTF-8) is a problem too, checked through the reader Charter uses (Prompt::ReadSection), so a section is never dropped in silence, and a name that is no lens is the unknown key it always was. Nothing lists a directory, so what lies beside the files is no concern of the config's: a directory listed would have to tolerate or refuse every foreign entry. The run logs which charters got one. The better-solution charter gains a consumer's general entry (2026-10-31: a mechanism reworked a second time in one submission is the signal to derive the fix at every layer the data crosses). The procedure names the section wherever it names the charter: among the config's keys, in the lens inputs, in the reuse rule (an edit to either re-runs the lens) and in the feedback loop, which routes a repository's own lesson to its section and a general one to the shipped charter.
128 lines
8.2 KiB
C++
128 lines
8.2 KiB
C++
// SPDX-License-Identifier: AGPL-3.0-only
|
|
// SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
|
|
|
export module Crafter.Review:Prompt;
|
|
import std;
|
|
import :Json;
|
|
|
|
// The system text and the layered prompt: the run layer, shared by every
|
|
// process of the run, then the lens layer, shared per lens, then the tail,
|
|
// this pass. Byte-identical prefixes are what the shared prompt cache keys
|
|
// on, so every literal here is fixed to the byte (the goldens hold them).
|
|
export namespace Crafter::Review::Prompt {
|
|
constexpr std::string_view SepLens = "\n\n==================== LENS ====================\n\n";
|
|
constexpr std::string_view SepTail = "\n\n==================== SCOPE OF THIS PASS ====================\n\n";
|
|
constexpr std::string_view SepRun = "\n\n==================== THIS RUN ====================\n\n";
|
|
|
|
extern const std::string_view GenericVocab;
|
|
// The kernel modes' vocabularies: every lens's, and a maintainer or
|
|
// recipient persona's.
|
|
extern const std::string_view GenericVocabKernel;
|
|
extern const std::string_view PersonaVocab;
|
|
// WHOLE_TEXT['first-repo'] and WHOLE_TEXT['functional'].
|
|
extern const std::string_view WholeFirstRepo;
|
|
extern const std::string_view WholeFunctional;
|
|
// WHOLE_TEXT['first'], ['all'] and ['persona']: the kernel modes' whole
|
|
// passes - the series as an approach, the consistency of the whole, the
|
|
// artifact read as one reviewer.
|
|
extern const std::string_view WholeFirst;
|
|
extern const std::string_view WholeAll;
|
|
extern const std::string_view WholePersona;
|
|
extern const std::string_view FunctionalBlockHint;
|
|
extern const std::string_view ShotRules;
|
|
// KIND_HINTS_REPO
|
|
extern const std::string_view HintOutside;
|
|
extern const std::string_view HintAbsent;
|
|
// KIND_HINTS: the kernel modes' hints - the anchor unit, the reference
|
|
// list, and the two per-patch slots.
|
|
extern const std::string_view HintAnchor;
|
|
extern const std::string_view HintRefs;
|
|
extern const std::string_view HintOutsideKernel;
|
|
extern const std::string_view HintAbsentKernel;
|
|
// The block hints of the commit-truth lens (2026-10-31): a message unit,
|
|
// and a unit of a documentation file; and the kernel modes' text hint.
|
|
extern const std::string_view TextBlockHintRepo;
|
|
extern const std::string_view DocBlockHintRepo;
|
|
extern const std::string_view TextBlockHint;
|
|
// SLOT_DUTIES: what a slot pass of a lens covers beyond the slot's
|
|
// question; empty for every other lens and slot.
|
|
std::string_view SlotDuty(std::string_view lensFile, std::string_view unitId);
|
|
|
|
// The repository's own section file per lens file (the config's
|
|
// lenses.<name>.section), appended to that charter by Charter. Empty:
|
|
// the shipped texts alone. Set by the run.
|
|
void SetLensSections(std::map<std::string, std::filesystem::path> files);
|
|
// A shipped lens text's path.
|
|
std::filesystem::path LensFile(std::string_view name);
|
|
// _common-repo.md with the artifact kind filled in; the kernel modes
|
|
// _common.md (a mailing-list reply, a patch series).
|
|
std::string SystemText(std::string_view mode = "commits");
|
|
// A repository's section file as every reader takes it (2026-11-01, the
|
|
// self-review's round 16): absent (no entry at all), its text, or present
|
|
// but unusable - a dangling or looping link, no regular file, unreadable,
|
|
// not UTF-8 - with the problem said. The config reports a named file that
|
|
// is absent or unusable (Config::SectionProblems) and Charter refuses
|
|
// both, so a section is never dropped in silence.
|
|
struct Section {
|
|
bool present = false;
|
|
std::string text;
|
|
std::string problem;
|
|
};
|
|
Section ReadSection(const std::filesystem::path& file);
|
|
// The lens's charter, read with universal newlines: the shipped text,
|
|
// then one blank line and the repository's section when it has one.
|
|
std::string Charter(std::string_view lensFile);
|
|
|
|
// INPUTS, the artifact with line numbers, the inventory. trees: as they
|
|
// are spelled to the lens; contextPaths may be empty; a subsystem names
|
|
// the journal's ledger and captures the lenses may read.
|
|
std::string RunLayer(std::string_view artifactRel, std::string_view base, std::string_view date, std::span<const std::string> trees, std::string_view hash,
|
|
std::span<const std::string> lines, const Json& units, std::span<const std::string> contextPaths = {},
|
|
std::string_view repoName = "the repository", std::string_view subsystem = {});
|
|
// The kernel modes' run layer: the journal's inputs, the trees, the
|
|
// reviewers with a persona, and the references digest after the
|
|
// inventory.
|
|
std::string RunLayerKernel(std::string_view mode, std::string_view artifactRel, std::string_view subsystem, std::string_view base, std::span<const std::string> reviewers,
|
|
std::string_view date, std::span<const std::string> trees, std::string_view hash, std::span<const std::string> lines, const Json& units,
|
|
std::string_view refDigest, std::span<const std::string> contextPaths = {});
|
|
|
|
// APPLICATION UNDER TEST: what the processes of a lens with the browser
|
|
// environment are told about the running application — from the
|
|
// consumer's functional config, the login fixture the driver found and the
|
|
// TOTP helper's exact command. slots: the stacks are the bring-up's
|
|
// slots, one per pass, and this block, shared by every pass of the lens,
|
|
// names none of them; the pass's own is in its user message (StackText).
|
|
// A nullopt fixture or command prints as None.
|
|
std::string AppBlock(const Json& functional, const std::optional<std::string>& loginFixture = std::nullopt,
|
|
const std::optional<std::string>& totpCommand = std::nullopt, bool slots = false);
|
|
// STACK FOR THIS PASS: the slot a pass holds, in its user message, so
|
|
// the system prompt every pass of the lens shares stays byte-identical.
|
|
std::string StackText(const Json& stack, const std::optional<std::string>& totpCommand);
|
|
// DATABASE UNDER TEST: the exact helper command (the URL stays in the
|
|
// driver's broker, never here), what the driver checked before the gate
|
|
// (dbUser: the role of the stacks' connections, nullopt when they differ;
|
|
// bypass: whether that role bypasses row-level security, nullopt says
|
|
// nothing), what one call is, how to act as an API caller, the limits,
|
|
// the evidence, the owner's notes.
|
|
std::string DbBlock(const Json& supabase, std::string_view sqlCommand, const std::optional<std::string>& dbUser, bool withApp = false,
|
|
const std::optional<std::string>& checked = std::nullopt, std::optional<bool> bypass = std::nullopt);
|
|
// The charter, the application and database blocks when there are
|
|
// any, the dispositions, the whole pass's summary; for a persona first
|
|
// who they are and the calibration map (the first 6000 characters of
|
|
// their lore listing).
|
|
std::string LensLayer(std::string_view lensFile, std::string_view charterText, std::string_view dispositionsBlock, std::string_view app = {},
|
|
std::string_view wholeSummary = {}, std::string_view db = {}, std::string_view persona = {}, std::string_view corpus = {});
|
|
// The scope of one pass: a whole pass's units, a slot's question, or a
|
|
// block's unit text. A kernel lens's job gets the kernel texts.
|
|
std::string Tail(const Json& job, const Json& units, std::span<const std::string> lines, std::string_view wholeSummary = {});
|
|
// kernel: the kernel modes' line, which also says to read the prefetched
|
|
// raw files instead of fetching.
|
|
std::string BudgetLine(const Json& job, bool kernel = false);
|
|
// The appended system prompt of a pass: the common charter text, the run
|
|
// layer and the lens layer, byte-identical for every pass of a lens in a
|
|
// run.
|
|
std::string SystemPrompt(std::string_view systemText, std::string_view run, std::string_view lens);
|
|
// The stdin user message of a pass: only what differs between passes. A
|
|
// null job adds no budget line.
|
|
std::string UserPrompt(std::string_view tail, const Json& job = nullptr, std::string_view stack = {}, bool kernel = false);
|
|
}
|