amsd-pipeline-shared 0.5.11 → 0.5.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/README.md +13 -0
  2. package/docs/gateway-baseline-2.0.80.md5 +130 -0
  3. package/docs/gateway-files.txt +131 -0
  4. package/orchestrations/prompts/templates/ac-classification.json +32 -0
  5. package/orchestrations/prompts/templates/ac-elaboration.json +22 -0
  6. package/orchestrations/prompts/templates/ac-gate-codeline-assignment.json +27 -0
  7. package/orchestrations/prompts/templates/agent-name-refusal.json +15 -0
  8. package/orchestrations/prompts/templates/agent-plan-mode.json +22 -0
  9. package/orchestrations/prompts/templates/agent-proposal.json +40 -0
  10. package/orchestrations/prompts/templates/agent-retry-prefix.json +47 -0
  11. package/orchestrations/prompts/templates/assign-agent-roles.json +22 -0
  12. package/orchestrations/prompts/templates/bug-fix-story.json +33 -0
  13. package/orchestrations/prompts/templates/change-reviewer.json +30 -0
  14. package/orchestrations/prompts/templates/code-graph-detective.json +41 -0
  15. package/orchestrations/prompts/templates/codeline-bridge.json +20 -0
  16. package/orchestrations/prompts/templates/content-retry-correction.json +28 -0
  17. package/orchestrations/prompts/templates/coordinator-amendment.json +37 -0
  18. package/orchestrations/prompts/templates/corrective-note.json +24 -0
  19. package/orchestrations/prompts/templates/cpa-inference.json +29 -0
  20. package/orchestrations/prompts/templates/cpa-system.json +20 -0
  21. package/orchestrations/prompts/templates/declared-packages.json +14 -0
  22. package/orchestrations/prompts/templates/detective-extract.json +16 -0
  23. package/orchestrations/prompts/templates/detective-overall-plan-given.json +19 -0
  24. package/orchestrations/prompts/templates/detective-overall-plan.json +26 -0
  25. package/orchestrations/prompts/templates/detective-prescription.json +22 -0
  26. package/orchestrations/prompts/templates/detective-retry-note.json +20 -0
  27. package/orchestrations/prompts/templates/detective-shared-package.json +28 -0
  28. package/orchestrations/prompts/templates/discovery-vocabulary.json +23 -0
  29. package/orchestrations/prompts/templates/e2e-route-check.json +22 -0
  30. package/orchestrations/prompts/templates/estate-survey.json +32 -0
  31. package/orchestrations/prompts/templates/estimation-assessment.json +26 -0
  32. package/orchestrations/prompts/templates/fix-plan-shared.json +19 -0
  33. package/orchestrations/prompts/templates/guard-vocabulary-codegraph.json +25 -0
  34. package/orchestrations/prompts/templates/guard-vocabulary-documentation.json +21 -0
  35. package/orchestrations/prompts/templates/guard-vocabulary.json +34 -0
  36. package/orchestrations/prompts/templates/hybrid-prephase-coordinator.json +16 -0
  37. package/orchestrations/prompts/templates/inference-ladder-coordinator.json +27 -0
  38. package/orchestrations/prompts/templates/kb-enforcement-synthesis.json +28 -0
  39. package/orchestrations/prompts/templates/lint-ac-remediator.json +20 -0
  40. package/orchestrations/prompts/templates/lint-fixer.json +19 -0
  41. package/orchestrations/prompts/templates/manifest-analysis.json +13 -0
  42. package/orchestrations/prompts/templates/mint-existing-roster.json +25 -0
  43. package/orchestrations/prompts/templates/new-dependency-directive.json +28 -0
  44. package/orchestrations/prompts/templates/new-dependency-lockfile-note.json +20 -0
  45. package/orchestrations/prompts/templates/phase-assessment-header.json +19 -0
  46. package/orchestrations/prompts/templates/pipeline-tools-command.json +13 -0
  47. package/orchestrations/prompts/templates/pipeline-tools-hosted.json +12 -0
  48. package/orchestrations/prompts/templates/plan-corrective.json +21 -0
  49. package/orchestrations/prompts/templates/plan-producer.json +24 -0
  50. package/orchestrations/prompts/templates/plan-reviewer.json +20 -0
  51. package/orchestrations/prompts/templates/prd-change-reviewer-mode-rules.json +28 -0
  52. package/orchestrations/prompts/templates/prd-change-reviewer-spec.json +33 -0
  53. package/orchestrations/prompts/templates/prd-change-reviewer.json +27 -0
  54. package/orchestrations/prompts/templates/prd-change-summarizer-text.json +19 -0
  55. package/orchestrations/prompts/templates/prd-change-summarizer-tool.json +21 -0
  56. package/orchestrations/prompts/templates/prd-configuration-block.json +24 -0
  57. package/orchestrations/prompts/templates/prd-generation.json +16 -0
  58. package/orchestrations/prompts/templates/prd-model-coordinator.json +24 -0
  59. package/orchestrations/prompts/templates/previous-refusal.json +15 -0
  60. package/orchestrations/prompts/templates/profile-augmentor.json +24 -0
  61. package/orchestrations/prompts/templates/project-prompt-generation.json +54 -0
  62. package/orchestrations/prompts/templates/project-roster-review.json +11 -0
  63. package/orchestrations/prompts/templates/prompt-claim-adjudication.json +21 -0
  64. package/orchestrations/prompts/templates/prompt-review.json +48 -0
  65. package/orchestrations/prompts/templates/qa-brownfield-scope.json +36 -0
  66. package/orchestrations/prompts/templates/qa-evidence-labels.json +28 -0
  67. package/orchestrations/prompts/templates/qa-fuzz-weaver.json +35 -0
  68. package/orchestrations/prompts/templates/qa-mutant-hunter.json +28 -0
  69. package/orchestrations/prompts/templates/qa-oracle-evidence.json +35 -0
  70. package/orchestrations/prompts/templates/qa-perf-sentinel.json +30 -0
  71. package/orchestrations/prompts/templates/qa-review-ranger.json +28 -0
  72. package/orchestrations/prompts/templates/qa-sast-sentinel.json +35 -0
  73. package/orchestrations/prompts/templates/qa-spec-validator.json +30 -0
  74. package/orchestrations/prompts/templates/release-line-port.json +22 -0
  75. package/orchestrations/prompts/templates/repro-feedback.json +31 -0
  76. package/orchestrations/prompts/templates/repro-role.json +32 -0
  77. package/orchestrations/prompts/templates/repro-test-writer.json +55 -0
  78. package/orchestrations/prompts/templates/retry-extension-coordinator.json +22 -0
  79. package/orchestrations/prompts/templates/review-ac-remediator.json +24 -0
  80. package/orchestrations/prompts/templates/review-finding-routing.json +17 -0
  81. package/orchestrations/prompts/templates/review-scope-block.json +18 -0
  82. package/orchestrations/prompts/templates/roster-review.json +46 -0
  83. package/orchestrations/prompts/templates/roster-specialisation-one.json +14 -0
  84. package/orchestrations/prompts/templates/roster-specialisation-plan.json +12 -0
  85. package/orchestrations/prompts/templates/roster-specialisation.json +24 -0
  86. package/orchestrations/prompts/templates/roster-tool-grant.json +20 -0
  87. package/orchestrations/prompts/templates/runtime-boundary-review.json +30 -0
  88. package/orchestrations/prompts/templates/shared-file-ownership.json +24 -0
  89. package/orchestrations/prompts/templates/skill-assessment-postphase.json +22 -0
  90. package/orchestrations/prompts/templates/skill-assessment-prephase.json +35 -0
  91. package/orchestrations/prompts/templates/skills-coordinator.json +19 -0
  92. package/orchestrations/prompts/templates/spec-agent-openspec.brownfield.json +67 -0
  93. package/orchestrations/prompts/templates/spec-agent-openspec.json +63 -0
  94. package/orchestrations/prompts/templates/spec-agent-speckit-refine.json +30 -0
  95. package/orchestrations/prompts/templates/spec-agent-speckit.json +28 -0
  96. package/orchestrations/prompts/templates/spec-authoring-rules.json +25 -0
  97. package/orchestrations/prompts/templates/spec-brownfield-mode.json +33 -0
  98. package/orchestrations/prompts/templates/spec-context-fragments.json +39 -0
  99. package/orchestrations/prompts/templates/spec-coordinator-review.json +29 -0
  100. package/orchestrations/prompts/templates/spec-coordinator.json +26 -0
  101. package/orchestrations/prompts/templates/spec-model-review.json +23 -0
  102. package/orchestrations/prompts/templates/spec-review-criteria.json +23 -0
  103. package/orchestrations/prompts/templates/spec-shared-consumer.json +20 -0
  104. package/orchestrations/prompts/templates/spec-story-block.json +42 -0
  105. package/orchestrations/prompts/templates/speckit-split-rules.json +20 -0
  106. package/orchestrations/prompts/templates/squad-coder.json +19 -0
  107. package/orchestrations/prompts/templates/squad-leader.json +19 -0
  108. package/orchestrations/prompts/templates/squad-security-auditor.json +19 -0
  109. package/orchestrations/prompts/templates/squad-tester.json +19 -0
  110. package/orchestrations/prompts/templates/story-ac-remediator.json +29 -0
  111. package/orchestrations/prompts/templates/story-diff-not-inlined.json +16 -0
  112. package/orchestrations/prompts/templates/story-file-generation.json +28 -0
  113. package/orchestrations/prompts/templates/story-implementation.json +25 -0
  114. package/orchestrations/prompts/templates/story-kind-hint-defect.json +18 -0
  115. package/orchestrations/prompts/templates/story-kind-hint-other.json +20 -0
  116. package/orchestrations/prompts/templates/story-plan-agent.json +31 -0
  117. package/orchestrations/prompts/templates/story-writer-main.json +96 -0
  118. package/orchestrations/prompts/templates/story-writer.json +28 -0
  119. package/orchestrations/prompts/templates/survey-review.json +38 -0
  120. package/orchestrations/prompts/templates/tc-writer.json +36 -0
  121. package/orchestrations/prompts/templates/test-gate-finding.json +27 -0
  122. package/orchestrations/prompts/templates/test-ownership.json +38 -0
  123. package/orchestrations/prompts/templates/tools-coordinator.json +18 -0
  124. package/orchestrations/prompts/templates/topology-router.json +30 -0
  125. package/orchestrations/prompts/templates/update-invalidated-tests.json +33 -0
  126. package/orchestrations/prompts/templates/vc-coverage.json +20 -0
  127. package/orchestrations/prompts/templates/vc-regenerate.json +33 -0
  128. package/orchestrations/prompts/templates/vc-review.json +27 -0
  129. package/orchestrations/prompts/templates/worktree-autocommit-message.json +27 -0
  130. package/orchestrations/prompts/templates/writer-codegraph-block.json +25 -0
  131. package/orchestrations/prompts/templates/writer-plan-section.json +28 -0
  132. package/orchestrations/prompts/templates/writer-string-invariants.json +17 -0
  133. package/orchestrations/scripts/lib/project-prompt-contract.js +414 -0
  134. package/orchestrations/scripts/refresh-project-prompts.js +96 -0
  135. package/package.json +1 -1
@@ -0,0 +1,30 @@
1
+ {
2
+ "$why": [
3
+ "ONE template replacing THREE near-identical copies in run-agent-orchestration.sh",
4
+ "(ac_patch, profile_creation, profile_addendum), 2026-08-15.",
5
+ "",
6
+ "All three asked the same question in the same shape and differed only in the evidence",
7
+ "section. Three copies meant a wording fix was a three-place edit, and the copies had",
8
+ "already begun to drift: two showed a diff and one showed BEFORE/AFTER separately.",
9
+ "",
10
+ "It is NOT merged with prd-change-reviewer, which looks similar and is not the same prompt:",
11
+ "that one carries a read-only-tools paragraph and a different output example",
12
+ "(\"issues\":[\"<issue1>\"] with a reason, versus empty here). Merging them would have silently",
13
+ "changed what two different agents are told.",
14
+ "",
15
+ "The evidence SECTION is one value, heading included, because each caller has different",
16
+ "evidence to show — a diff, or a before and an after. A template that branches is a program."
17
+ ],
18
+ "body": "STORY: __STORY__\nCHANGE TYPE: __CHANGE_TYPE__\n\n__EVIDENCE__\n\nEmit ONLY: {\"verdict\":\"pass|fail\",\"issues\":[],\"reason\":\"\"}",
19
+ "description": "Validate a proposed change against its evidence and return pass or fail.",
20
+ "id": "change-reviewer",
21
+ "placeholders": [
22
+ "__CHANGE_TYPE__",
23
+ "__EVIDENCE__",
24
+ "__STORY__"
25
+ ],
26
+ "version": 1,
27
+ "seams": [
28
+ "prd-change-reviewer"
29
+ ]
30
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "id": "code-graph-detective",
3
+ "layer": "project",
4
+ "version": 2,
5
+ "description": "The brownfield investigator: locates where a ticket lands in a real repository and prescribes the minimal change, grounded in tools rather than inference.",
6
+ "$why": [
7
+ "MIGRATED OUT OF spec-mode-runner.js ON 2026-08-12, byte-identical to the literal it replaced.",
8
+ "This prompt decides where every ticket lands and what every writer builds. It has produced two different prescriptions for the SAME ticket and repository 40 minutes apart — one carrying the step that made the feature work, one without it — so changing how it reasons must be a diff on a document, reviewable on its own, not a patch to engine source.",
9
+ "Prose inside a code literal IS code. The reviewer prompt, held in a shell string, had a raw quote close the string and two backticks execute as commands, silently deleting words from what the model was sent. A prompt in a data file cannot do that.",
10
+ "_kindHintBlock and correctiveContext are ADJACENT in the source with no separator, and the library reads __A____B__ as a single token, so they render as one value the caller concatenates.",
11
+ "NO PROJECT FACT BELONGS IN THIS FILE. Under the target design a mint-time agent generates each project prompt using this template as its guide, so a client, stack or ticket name here becomes wrong output for every future project.",
12
+ "v2, 2026-08-12: added deliveryRole and runsIn. A prescription was accepted in which every site carried or verified and none produced — it wired a change signal and never obtained the value, so the built feature re-rendered stale data. It also placed a browser-only subscription inside a server entry point. Both are now FIELDS, because this prompt's own rule is that nothing reads prose.",
13
+ "2026-08-18: the estate survey had already named the file, the function, the line, the defect and the missing test for this codeline, and this agent re-derived all of it from scratch — the survey's output was consumed only by the mint. It now arrives as a HYPOTHESIS to verify against the index, empty whenever there is nothing trustworthy to hand over.",
14
+ "",
15
+ "2026-08-19: fix sites named only the source implementing a behaviour, never the configuration governing whether it is allowed to happen. A live brownfield run asked for a feature that required embedding the site in an iframe; the codeline's own config sets frame-ancestors 'self' and X-Frame-Options SAMEORIGIN, and that file appeared ZERO times in the story across three runs. No agent could act on what was never in scope. The file list is supplied by the caller from the codeline's own manifest (client-env-boundary-plugin's configSurface) — this template names no framework."
16
+ ],
17
+ "placeholders": [
18
+ "__ESTIMATION_ASSESSMENT__",
19
+ "__CONFIG_SURFACE__",
20
+ "__KIND_AND_CORRECTIVE_CONTEXT__",
21
+ "__PRESCRIPTION_RULES__",
22
+ "__PRESEED_BLOCK__",
23
+ "__STORY_DESCRIPTION__",
24
+ "__STORY_TITLE__",
25
+ "__SURVEY_HYPOTHESIS__",
26
+ "__STORY_ACS__",
27
+ "__PIPELINE_TOOLS__"
28
+ ],
29
+ "body": "You are investigating this ticket in the repository you work in (its root is your working directory).\n__KIND_AND_CORRECTIVE_CONTEXT__\nTICKET (read it, then decide for YOURSELF which few domain nouns matter — do not treat every word as a search term):\nTitle: __STORY_TITLE__\n__STORY_DESCRIPTION____STORY_ACS____PIPELINE_TOOLS__\n__SURVEY_HYPOTHESIS____ESTIMATION_ASSESSMENT__\n__PRESEED_BLOCK__\n__PRESCRIPTION_RULES__\n\n## CONFIGURATION THAT GOVERNS THIS BEHAVIOUR\n\nThis codeline carries these configuration files:\n__CONFIG_SURFACE__\n\nA change can be written perfectly and still be impossible, because configuration decides what the\ncode is PERMITTED to do — which origins may embed or be contacted, what reaches the browser, what\nthe build emits. If the behaviour this story asks for depends on any of them, name that file in\nyour fix sites alongside the source, and say in one line what must change there and why. If it\ndoes not, say nothing about them: an irrelevant configuration file in the fix sites costs a writer\na wasted edit.\n\n\nREAD THE FILE BEFORE YOU QUOTE IT. Once you have a candidate file, run `show <file>` and look at the real lines. Your \"brokenLine\" must be COPIED EXACTLY from that output — it is checked character-for-character against the file, after whitespace normalisation. Do NOT reconstruct the line from symbol names: on 2026-07-26 that produced `lineItemKey === orderLineItem.id`, a plausible-looking expression using an identifier that exists nowhere in the repository, and the answer was rejected. `show` accepts a line range so you can read just the region you care about.\n\nCRITICAL REALITY ANCHOR: if the CodeGraph tool does not return a file or symbol, it does NOT exist in this codebase. Do not infer, assume, or extrapolate file paths, function signatures, or variable names from naming patterns — that is exactly how `lineItemKey` was invented. The index answers only for what it parsed, so a miss is a question, not an answer. If you believe something exists and CodeGraph did not return it, PROVE it before reasoning about it with the search tool under YOUR TOOLS (an exact symbol, or a file by part of its name).\n\nIf your fix calls a method or function from a THIRD-PARTY package (not this repo's own code), a name existing somewhere in that package is not the same as it being the RIGHT way to call it — a symbol can be a real, internal implementation detail the package's own docs never call directly, or a static class method vs. an instance method, and picking the wrong one produces code that type-checks and fails at runtime. PROVE the real shape before naming it with the package-symbol tool under YOUR TOOLS (the package name and the method or function name). It reports whether the symbol is a direct/static call or needs an instance, and surfaces the package's own documented usage examples (README and JSDoc) so you can prefer the intended pattern over an internal detail that happens to exist.\n\nThat searches the real working tree, so a hit is ground truth and \"NOT FOUND\" is definitive absence. If both tools come back empty, the thing does not exist — say so and revise your hypothesis. Never write a name into your answer that no tool has shown you.\n\nCRITICAL — HOW TO ANSWER: Emit the JSON array as TEXT directly in your reply. Do NOT call WriteFile and do NOT write your answer to any file — the pipeline reads your reply text, not a file. If you write your answer to a file, it is LOST and the whole investigation is wasted. Use ONLY the tools under YOUR TOOLS (including CodeGraph's `show`, which you MUST use before quoting a line); use no other tool.\n\nNAME THE FORMAT, DO NOT DESCRIBE IT. If your fix depends on the SHAPE of a string — a prefix, suffix, separator, delimiter — you must QUOTE THE EXACT LITERAL (e.g. '#') or name the constant that defines it (e.g. DIVIDER). Saying \"a prefix match that accounts for the suffix\" without stating the suffix is not implementable: on 2026-07-26 exactly that wording made the implementer guess '-' where the repository uses '#', and the fix could never match. This is machine-checked.\n\nPREFER THE PARSER OVER THE WRITER. If a helper CONSTRUCTS the value (getX/buildX/toX) and another READS it (parseX/fromX), prescribe the reader. Naming the writer invites the implementer to reconstruct the format by hand — which is how the above happened. The best fix does no string surgery at all, because the helper owns the format.\n\nVERIFY THIRD-PARTY METHOD CALLS with the package-symbol tool before prescribing them (see above) — a name existing in a package is not proof it is called the way you assume.\n\nSAY WHAT EACH CHANGE DOES TO THE VALUE — \"deliveryRole\" is REQUIRED, and it is the field this\nprompt exists to get right. Exactly one of:\n\n \"produces\" this change is what makes the new or corrected value EXIST. It reads it, fetches\n it, queries it, computes it, or changes configuration so that an existing call\n starts returning it. If you removed only this change, the value would never come\n into being.\n \"carries\" this change moves, stores, re-renders or re-exposes a value that something ELSE\n produced, or it subscribes to a signal saying the value changed. Reacting to a\n change is NOT obtaining one.\n \"verifies\" this change does nothing to the value; the file only needs confirming once the\n other sites change. Use it with changeRequired:false.\n\nA PLAN IN WHICH NOTHING PRODUCES IS NOT A PLAN. If every site you name carries or verifies, you\nhave described the delivery of a value nobody obtains, and the implementation will do visibly\nnothing while looking correct — a subscription firing, state updating, a view re-rendering, and\nthe same stale value on the screen. Before you answer, find the site that PRODUCES. If the\ncapability genuinely needs no new value, say so in \"reason\"; if you cannot find where the value\nwould come from, say THAT rather than naming a carrier and hoping.\n\nSAY WHERE EACH CHANGE RUNS — \"runsIn\" is REQUIRED. One of \"server\", \"browser\", \"both\", \"n/a\".\nAn API that only exists in one of those cannot be called from the other, and a prescription that\nputs it in the wrong place cannot be implemented at all: the implementer either fails or quietly\ndoes something different. Check what the surrounding function is — an entry point that runs\nbefore a response is sent is not the same place as code running after it is displayed. If a\nchange subscribes to something, subscribing usually runs where the events happen; obtaining the\nvalue may run somewhere else, and those are then TWO sites, not one.\n\nSAY WHETHER THE FILE MUST BE EDITED — \"changeRequired\" is REQUIRED. Set it true when your fix means editing THIS file. Set it FALSE when the file is genuinely part of the fix but needs no edit of its own: it already does the right thing, and will simply behave correctly once the other sites change. A consumer that reads state from a provider you are fixing is the usual case. This is not a lesser finding and must not be dropped — a downstream gate requires a real diff in every site you mark true, so marking a verify-only file true makes the story impossible to complete: the implementer changes nothing (correctly), the gate rejects it, and every retry repeats. Saying it in the \"fix\" prose is not enough; nothing reads prose.\n\nDECLARE ANY PACKAGE YOUR FIX NEEDS — \"requiredPackages\" is REQUIRED and is machine-verified. List the BARE package names, exactly as they appear in this project's manifest (e.g. \"some-sdk\", \"@scope/pkg\"), for every third-party package your fix imports or configures. Use [] when the fix needs none — that is the common case and is not a failure. Each name is checked against what this codeline actually declares and installs: a package that is not there means your fix CANNOT be implemented as written, and prescribing it produces a change that type-checks, passes tests, and fails for a real user. Prefer a fix built on what is already installed; if the work genuinely requires a package this project does not have, still declare it — that is the honest answer and the pipeline needs to see it, whereas an approach invented to avoid naming it is the failure this field exists to prevent.\n\nOutput ONLY a JSON array (no prose, no markdown fences), then stop. The \"fix\" field is REQUIRED and must be a concrete, minimal instruction naming the exact change and any existing helper to reuse. The \"helper\" field must be the BARE SYMBOL NAME of the existing function you are telling the implementer to reuse (so it can be machine-verified to actually exist) — leave it \"\" if the fix genuinely needs no existing helper. Do NOT invent a helper name; only put a symbol you actually saw in the tool output:\n[{\"file\":\"<repo-relative path>\",\"function\":\"<symbol>\",\"reason\":\"<why THIS computes the value, not just displays it>\",\"brokenLine\":\"<the exact existing expression that is wrong, copied verbatim from that file>\",\"fix\":\"<the exact minimal change: which line/expression to change, to what, and which EXISTING helper (symbol + import path) to reuse — never 'write a new function' if one already exists>\",\"helper\":\"<bare existing symbol name to reuse, or empty>\",\"changeRequired\":<true if this file must be EDITED; false if it is implicated but needs NO edit — it already behaves correctly and only needs to be VERIFIED once the other sites change>,\"requiredPackages\":[\"<bare package name this fix needs>\"],\"deliveryRole\":\"produces|carries|verifies\",\"runsIn\":\"server|browser|both|n/a\"}]",
30
+ "seams": [
31
+ "code-graph-detective"
32
+ ],
33
+ "mayBeEmpty": [
34
+ "__ESTIMATION_ASSESSMENT__",
35
+ "__SURVEY_HYPOTHESIS__",
36
+ "__STORY_ACS__"
37
+ ],
38
+ "$whyEstimationAssessmentMayBeEmpty": "__ESTIMATION_ASSESSMENT__ (2026-09-28): the estimation application's assessment of this story's ticket (EPAM_ESTIMATION_MANIFEST, rendered by lib/handlers/estimation-manifest.js with this agent's framing from the engine template estimation-assessment). Absent is the ordinary state: a run with no manifest, or a ticket the manifest does not cover. It sits directly beside its neighbour with no separator of its own, so an absent assessment renders the prompt byte-for-byte as before.",
39
+ "$whyMayBeEmpty": "Declared 2026-08-27. The estate survey may reach no hypothesis for a story, and the detective can search a codeline without one — that is a real state, not a failed lookup. Undeclared, the render threw and the seam was skipped with 'code-graph-detective unavailable', which then left __FIX_SITE_BLOCK__ empty for the spec agent downstream.",
40
+ "_storyAcs": "__STORY_ACS__ RESTORED 2026-09-11 as a BLOCK, mayBeEmpty: the caller supplies the heading AND the numbered criteria together, or nothing. ea920ee7 removed the placeholder because brownfield never has acceptance criteria (it judges on VCs) and an empty heading is worse than none — that ruling stands: on brownfield the prompt carries no heading. It threw away the greenfield case: a greenfield PRD is authored WITH acceptance criteria and they are in scope (operator, 2026-09-11), so this seam sees them there. Absent is a real state; present is the greenfield contract."
41
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "$why": [
3
+ "Moved out of run-agent-orchestration.sh on 2026-08-16.",
4
+ "",
5
+ "Extracts the exported surface of a completed codeline so a later lane's detective can read it. Producers run before consumers precisely so this exists when it is needed."
6
+ ],
7
+ "description": "Extracts a completed codeline's exported surface as a contract for later lanes.",
8
+ "seams": [
9
+ "codeline-bridge-agent"
10
+ ],
11
+ "id": "codeline-bridge",
12
+ "version": 1,
13
+ "body": "## Variables for this run\n\n- BRIDGE_SRC_CODELINE: __BCL__\n- BRIDGE_SRC_DIR: __BWT__\n- BRIDGE_OUT_FILE: __BRIDGE_OUT__\n- BRIDGE_PRD_FILE: __BPRD__\n\nExtract the exported API surface from the '__BCL__' codeline files and write the cross-codeline contract to __BRIDGE_OUT__.",
14
+ "placeholders": [
15
+ "__BRIDGE_OUT__",
16
+ "__BPRD__",
17
+ "__BCL__",
18
+ "__BWT__"
19
+ ]
20
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "$why": [
3
+ "Created 2026-08-17, when lib/content-retry.js was written.",
4
+ "",
5
+ "The correction a retry carries is TEXT SENT TO A MODEL, and it was composed in engine code.",
6
+ "Every other instruction an agent receives lives in this layer, reviewable as prose; this one",
7
+ "was a template literal inside a shared library, so nobody auditing the prompts would ever",
8
+ "see the words that actually reach the model on a retry.",
9
+ "",
10
+ "It is deliberately generic: it names no project, no agent, no artefact and no format. The",
11
+ "REASON and the previous answer are supplied by whichever call site rejected the answer, so",
12
+ "the same wording serves the vocabulary agent, the mint, and every parse site added later."
13
+ ],
14
+ "id": "content-retry-correction",
15
+ "version": 1,
16
+ "layer": "engine",
17
+ "description": "Tells an agent its previous answer was rejected, why, and what it sent.",
18
+ "seams": [],
19
+ "body": "YOUR PREVIOUS ANSWER WAS REJECTED: __REASON__\n\nThis is what you sent, and it could not be used:\n---\n__PREVIOUS_ANSWER__\n---\nAnswer again in exactly the format requested. Change nothing else.\n\n",
20
+ "placeholders": [
21
+ "__REASON__",
22
+ "__PREVIOUS_ANSWER__"
23
+ ],
24
+ "mayBeEmpty": [
25
+ "__REASON__"
26
+ ],
27
+ "$whyMayBeEmpty": "Declared 2026-08-27 by sweeping the CLASS rather than the instance, after three runs died on it one placeholder at a time. Every call site for these writes an explicit empty branch \u2014 the story is not being split, attempt one carries no forced-retry note, no documentation was fetched, the persona prefix is optional \u2014 so absence is a real state, which is the renderer's own test. Placeholders supplied by a lookup that may FAIL (`x || ''`) are deliberately NOT here: for those, empty means broken, and declaring them would hide the blank-brief defect the renderer exists to surface. Unanimity is required \u2014 one deliberate branch among several defensive lookups is not a licence."
28
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "$why": [
3
+ "Moved out of claude.sh on 2026-08-16.",
4
+ "",
5
+ "The COORDINATOR_PROMPT_AMENDMENT chain: text prepended to a writer's next attempt saying what went wrong last time. Four distinct situations, four bodies -- turns exhausted with the files already present, turns exhausted with nothing written, a defect escalated from a sibling story, and a deterministic check that failed.",
6
+ "",
7
+ "The first two differ in one consequential way: whether the deliverable already exists. Told the wrong one, a writer either rewrites files it should read, or reads for files that were never created.",
8
+ "",
9
+ "One body carried a whole conditional SECTION inside a ${VAR:+...} expansion -- the prior failure-analyst diagnosis, re-injected for context. Whether the writer saw it was decided by a parameter expansion, which is not a place anyone reads prompt text."
10
+ ],
11
+ "description": "What a writer is told about the previous attempt when its next one is prepared.",
12
+ "seams": [
13
+ "story-writer"
14
+ ],
15
+ "id": "coordinator-amendment",
16
+ "version": 1,
17
+ "bodies": {
18
+ "turns_exhausted_files_exist": "CRITICAL: The previous attempt exhausted all available turns without creating the required deliverable. These files already exist — their real content is injected in ## Existing File Contents; do not spend turns re-reading them. Use Edit for a targeted, minimal change and act on it immediately — do not re-explore the codebase beyond what's already injected.",
19
+ "turns_exhausted_nothing_written": "CRITICAL: The previous attempt exhausted all available turns without creating the required deliverable. Your FIRST action MUST be to call WriteFile to the exact absolute path listed under 'Files to Create/Modify' — do NOT read files, do NOT plan, do NOT investigate. Write the required file IMMEDIATELY as your very first action.",
20
+ "sibling_escalation": "\n## URGENT: Escalated defect from sibling story __ESCALATING_STORY_ID__\n__DIAGNOSIS__\nRequired fix: __REQUIRED_FIX__\nApply ONLY this fix to __TARGET_FILE__. Do not make any other changes to this file or any other file — this is a narrow, targeted patch, not a full re-implementation.",
21
+ "deterministic_check": "__EXISTING_AMENDMENT__\n## Deterministic Check Failure\n__VERIFICATION_FAILURE__\nThis was caught by an automated check before the test suite even ran — fix the exact issue named above.__PRIOR_DIAGNOSIS_SECTION__"
22
+ },
23
+ "placeholders": [
24
+ "__ESCALATING_STORY_ID__",
25
+ "__REQUIRED_FIX__",
26
+ "__TARGET_FILE__",
27
+ "__DIAGNOSIS__",
28
+ "__PRIOR_DIAGNOSIS_SECTION__",
29
+ "__VERIFICATION_FAILURE__",
30
+ "__EXISTING_AMENDMENT__"
31
+ ],
32
+ "$mayBeEmptyWhy": "__PRIOR_DIAGNOSIS_SECTION__ is absent on the FIRST deterministic-check violation, before any failure-analyst has run — claude.sh supplies it with ${_last_fa_diagnosis:+...}, which is empty by design in that state. Without this declaration engine-prompt.js threw, render_or_keep fell back to the PREVIOUS amendment, and the retry was never told what it did wrong: it repeated the same violation and HealingBroken then invoked the analyst the skip was meant to avoid. Live 2026-09-11 (openrouter 20260910T222155Z) that happened twice, at 00:58:55 and 01:02:35, both before the first healing event at 01:04:08, and never after — the timing matches the cause exactly. Only this placeholder is optional; every other value here is a real requirement. __EXISTING_AMENDMENT__ joined it 2026-09-13: the FIRST deterministic-check violation of a story has no earlier amendment to carry forward, and the same throw kept the retry uninformed of the deliverables it had not written (seen on every first violation in the £0 greenfield run).",
33
+ "mayBeEmpty": [
34
+ "__EXISTING_AMENDMENT__",
35
+ "__PRIOR_DIAGNOSIS_SECTION__"
36
+ ]
37
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "$why": [
3
+ "Moved out of run-agent-orchestration.sh on 2026-08-16.",
4
+ "",
5
+ "What an agent is told when its previous attempt broke its OWN instructions -- distinct from a retry after an unusable answer, because here the output was usable and wrong. Two seams used near-identical wording written out twice; they share it now."
6
+ ],
7
+ "description": "Tells an agent its previous attempt violated the instructions it was given, and what to do instead.",
8
+ "seams": [
9
+ "prd-change-reviewer",
10
+ "cpa-inference"
11
+ ],
12
+ "id": "corrective-note",
13
+ "version": 1,
14
+ "bodies": {
15
+ "phase_assessment": "__PFA_PROMPT_THIS_ATTEMPT__\n\nCRITICAL — YOUR PREVIOUS ATTEMPT VIOLATED YOUR OWN INSTRUCTIONS: __PFA_CORRECTIVE_NOTE__\nFix this and retry. Do not repeat the same mistake.",
16
+ "model_coordinator": "__MC_PROMPT__\n\nCRITICAL — YOUR PREVIOUS ATTEMPT VIOLATED YOUR OWN INSTRUCTIONS: __MC_CORRECTIVE_NOTE__\nFix this and retry. Do not repeat the same mistake."
17
+ },
18
+ "placeholders": [
19
+ "__PFA_PROMPT_THIS_ATTEMPT__",
20
+ "__PFA_CORRECTIVE_NOTE__",
21
+ "__MC_CORRECTIVE_NOTE__",
22
+ "__MC_PROMPT__"
23
+ ]
24
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "$why": [
3
+ "Moved out of lib/cpa-inference.js buildPrompt on 2026-08-15 (7 of 20).",
4
+ "",
5
+ "This prompt is mostly a DATA ENVELOPE: the story, the formula baseline, KB sources, code",
6
+ "signals, adjacent stories, the manifest and the detective's fix sites, each rendered as",
7
+ "JSON by the caller and joined. What is genuinely PROMPT here is the envelope itself and",
8
+ "the closing instruction, and that is what this template holds.",
9
+ "",
10
+ "Section assembly stays in the caller because it is filter(Boolean) logic — an absent",
11
+ "section removes its separator too, and a template cannot express that without becoming a",
12
+ "program."
13
+ ],
14
+ "body": "__SYSTEM_PROMPT__\n\n---\n\n__SECTIONS__\n\n---\n\nRespond with ONLY the JSON object as specified in your instructions. No prose, no markdown fences.",
15
+ "description": "Ask the estimator for an iteration count, given the story and everything known about it.",
16
+ "id": "cpa-inference",
17
+ "placeholders": [
18
+ "__SECTIONS__",
19
+ "__SYSTEM_PROMPT__"
20
+ ],
21
+ "version": 1,
22
+ "seams": [
23
+ "cpa-inference"
24
+ ],
25
+ "mayBeEmpty": [
26
+ "__SYSTEM_PROMPT__"
27
+ ],
28
+ "$mayBeEmpty": "__SYSTEM_PROMPT__ is optional input and the caller says so in its own signature: cpa-inference.js destructures `systemPrompt = ''`. The render refused that state, so a caller omitting an optional field got 'FATAL: prompt was given EMPTY values' instead of an estimate. Declaring it makes the template agree with the contract the caller already publishes."
29
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "$why": [
3
+ "Moved out of contextualize-stories.sh on 2026-08-15 (8 of 20). It was a QUOTED heredoc,",
4
+ "so it carries no interpolation at all — pure prompt prose, and the simplest possible case",
5
+ "of a prompt that had no business living in a shell script.",
6
+ "",
7
+ "It is the CPA's system prompt: the estimator's standing instructions, separate from the",
8
+ "per-story envelope in cpa-inference. The script already supported an external prompt file",
9
+ "via SYSTEM_PROMPT_FILE, so the mechanism for reading one from disk was already there — it",
10
+ "just defaulted to a copy embedded in the script."
11
+ ],
12
+ "body": "You are the Contextual Purveyor Agent (CPA).\nGoal: refine formula-based implementation estimates for a software story using provided context.\n\nRules:\n- Return strict JSON only.\n- Be conservative when confidence is low.\n- Surface concrete risk flags and missing knowledge areas.\n- Prefer practical effort realism over optimism.\n\nOutput schema:\n{\n \"confidence\": 0.0,\n \"complexityAdjustment\": 1.0,\n \"adjustedEstimate\": {\n \"aiMinutes\": 0,\n \"cost\": 0,\n \"tokens\": 0,\n \"turns\": 1\n },\n \"riskFlags\": [],\n \"missingKbCoverage\": [],\n \"citedSources\": [],\n \"reasoning\": \"short rationale\"\n}",
13
+ "description": "The estimator's standing instructions: refine a formula estimate conservatively and surface risk.",
14
+ "id": "cpa-system",
15
+ "placeholders": [],
16
+ "version": 1,
17
+ "seams": [
18
+ "cpa-inference"
19
+ ]
20
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "$why": [
3
+ "An agent that writes code or tests may use only what the codeline declares. A package present on disk and not",
4
+ "declared builds locally and fails for every consumer; an agent asked for a capability that needs one has to be",
5
+ "told the declaration, or it will reach for whatever happens to be installed.",
6
+ "",
7
+ "A fragment composed into an agent's prompt: no seam declares it, so it renders from the engine layer."
8
+ ],
9
+ "description": "Tells an agent which packages the codeline declares, and that it may use only those.",
10
+ "id": "declared-packages",
11
+ "version": 1,
12
+ "placeholders": ["__DECLARED_PACKAGES__"],
13
+ "body": "\n\n## PACKAGES THIS CODELINE DECLARES\n```json\n__DECLARED_PACKAGES__\n```\nUse only packages listed in `declared` (when `manifestRead` is false, none is known to be declared). A package present on disk but not listed is not available: never import it, and never add a dependency. If what you were asked needs a package that is not declared, say so in your final message instead of working around it.\n"
14
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "$why": [
3
+ "Moved out of spec-mode-runner.js runCodeGraphDetective on 2026-09-14. It was a template literal in code — the one prompt of the detective's second phase (no tools; extract the fix site from an investigation that ended in prose) — so the prompt layer could not see it: no project copy, no review, and the £0 rehearsal answered it from the catch-all with {} (brownfield harness run 1).",
4
+ "One prompt = one JSON file; a prompt in code is hidden."
5
+ ],
6
+ "description": "Extracts the single most-likely causal fix site from a detective investigation that ended in prose.",
7
+ "id": "detective-extract",
8
+ "seams": [
9
+ "code-graph-detective"
10
+ ],
11
+ "version": 1,
12
+ "placeholders": [
13
+ "__INVESTIGATION__"
14
+ ],
15
+ "body": "A code investigation of a bug produced the analysis below. Extract the single most-likely causal fix site and output ONLY a JSON array — no prose, no markdown fences, then stop. If the analysis is incomplete, output your BEST hypothesis from what it contains (a best guess beats nothing).\n[{\"file\":\"<repo-relative path>\",\"function\":\"<symbol>\",\"reason\":\"<why THIS computes the wrong value, not just displays it>\",\"fix\":\"<the exact minimal change: which line/expression to change and which EXISTING helper (symbol) to reuse>\",\"helper\":\"<bare existing symbol name to reuse, or empty>\"}]\n\n=== INVESTIGATION ===\n__INVESTIGATION__"
16
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "$why": [
3
+ "Operator, 2026-10-06: one plan for the story, written once and passed to every codeline as a shared artefact.",
4
+ "The first detective writes it (detective-overall-plan); the detective of every later codeline is given it here and",
5
+ "investigates its own codeline's part, rather than planning the story again from one codeline's view.",
6
+ "2026-10-06, real-model rounds: given a plan that gave it no change, a consumer lane marked its lock file and locale files as requiring change."
7
+ ],
8
+ "description": "Composed into the code-graph detective's prescription once the story has an overall plan: work this codeline's part of it, and say plainly where this codeline's code contradicts it.",
9
+ "id": "detective-overall-plan-given",
10
+ "seams": [
11
+ "code-graph-detective"
12
+ ],
13
+ "placeholders": [
14
+ "__OVERALL_PLAN__",
15
+ "__THIS_CODELINE__"
16
+ ],
17
+ "version": 1,
18
+ "body": "\nTHIS STORY ALREADY HAS ITS PLAN, written by the first investigation for every codeline it is worked in. You are investigating codeline \"__THIS_CODELINE__\": locate the fix sites for ITS part of the plan below, and nothing the plan gives to another codeline.\n__OVERALL_PLAN__\nWhere the plan gives this codeline no change of its own, none of your fix sites requires a change — receiving the provider's release (manifest, lock file, install) is not this codeline's work in this story.\nThe plan is the story's, not a lead to re-derive. Where this codeline's own code contradicts it — a use of the changed code the plan does not list, a part that cannot be done as stated — say so in the fix site's reason, naming what you found; do not write a different plan.\n"
19
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "$why": [
3
+ "Operator, 2026-10-06: \"when code detection returns multiple codelines we need an overall plan passed to each",
4
+ "codeline as a shared artefact\"; \"when there is only one codeline — one plan, same process\"; \"the manifest or",
5
+ "detective at the shared level should have recognised the consumer code blast radius and provided the plan for ALL",
6
+ "codelines\". AMSD-2974: each codeline's detective planned alone, so a library change shipped one major version",
7
+ "past two consumers' locked ranges and the only remedy anyone could name was editing those ranges. A real team",
8
+ "plans a change once, across every codeline it touches, and ships it on every release line its consumers are on.",
9
+ "2026-10-06, the real-model probe: the plan said consumers receive the release via their update script, which installs the latest release and would rewrite the very range the plan keeps.",
10
+ "2026-10-06, real-model run: the provider codeline listed the consumers' files (../<other codeline>/...) among its own fix sites.",
11
+ "2026-10-06, real-model rounds: the plan wrote a consumer's change as \"none in shared code; update installed package within range\", and that consumer's lane then prescribed its lock file.",
12
+ "",
13
+ "2026-10-06, real-model round: a consumer's change read \"none (dependency bump only; review own toast messages)\", and that lane then changed its locale file.",
14
+ "2026-10-06: a shared codeline is worked once per release line the plan names (lib/release-lines.sh); the plan says which line the codeline's own base is on, so no version arithmetic is written into the engine."
15
+ ],
16
+ "description": "Composed into every code-graph detective's prescription: before naming fix sites, write the one plan the whole story is worked from — every codeline's part, every consumer's blast radius, every release line.",
17
+ "id": "detective-overall-plan",
18
+ "seams": [
19
+ "code-graph-detective"
20
+ ],
21
+ "placeholders": [
22
+ "__PLAN_CODELINES__"
23
+ ],
24
+ "version": 4,
25
+ "body": "\nTHE OVERALL PLAN. This story is worked in the codelines below, and every one of them is worked from the plan you write here — it is the one plan for the whole story, not this codeline's notes. You can read each codeline at the location given.\n__PLAN_CODELINES__\nEstablish, by reading the code, not by assuming:\n1. EACH CODELINE'S PART: what it must change in its own code, or that it changes nothing — and the order the codelines must be worked in, when one needs another's change first.\n2. FOR EVERY PACKAGE ONE OF THESE CODELINES PROVIDES AND ANOTHER CONSUMES: the BLAST RADIUS — in each consumer, the files and calls that reach the code being changed, read in that consumer; and whether the change alters anything those calls depend on.\n3. THE RELEASE LINES the change must ship on, so that every consumer receives it through the range it ALREADY declares. A consumer's declared range is never changed by this story. Say how each consumer receives its release: within its declared range (an update the range already allows) — never by installing the latest release, which can move the range; read what a consumer's own scripts do before naming one. Each line is worked on its own branch from its base; say for each whether the provider codeline's own base is already on it (onCodelineBase). One line per distinct line the consumers' ranges require; for each, the base it is cut from (the newest existing release on that line, from the release facts above) and the version it ships as.\n\nWrite the plan as ONE JSON object between these tags, before your fix-site answer:\n<OVERALL_PLAN>\n{\"codelines\":[{\"codeline\":\"<name>\",\"part\":\"<what it changes in its own code, or that it changes nothing and how it receives the change>\",\"order\":1}],\"packages\":[{\"package\":\"<name, as its manifest declares it>\",\"providedBy\":\"<codeline>\",\"releaseLines\":[{\"line\":\"<the release line>\",\"base\":\"<the existing release it is cut from>\",\"version\":\"<the version it ships as>\",\"onCodelineBase\":<true if the provider codeline's own base is on this line — even when newer releases were cut on it since; the change merges forward onto it. false only for a different, older line>,\"carries\":\"<what this line carries: for a line off the codeline's own base, the change made on the codeline's own line, ported in full: the story's whole change on the codeline's own line — what is already there and what this plan adds — every part of it, adapted where this line's code differs>\"}],\"consumers\":[{\"codeline\":\"<codeline>\",\"declaredRange\":\"<as its manifest declares it>\",\"receivesVia\":\"<the version, from the release lines above>\",\"usage\":[\"<file>: <how it reaches the code being changed>\"],\"change\":\"<exactly none, or the change this consumer makes in its OWN code for this story — never none plus something to do or review>\"}]}]}\n</OVERALL_PLAN>\nReceiving the provider's release is never a consumer's change in this story — not its manifest, not its lock file, not an install: that release does not exist until the provider ships it.\nYour fix sites, after the plan, are files of THIS codeline only. Another codeline's files belong in the plan — its part and its usage — never among your fix sites.\nA story worked in ONE codeline writes the same plan: one entry under codelines, and packages empty unless that codeline provides one another codeline consumes.\n"
26
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "$why": [
3
+ "Moved out of spec-mode-runner.js on 2026-08-16. Two arms of one function: what the detective",
4
+ "is told to do on a DEFECT (trace the causal site, quote the broken expression) versus on",
5
+ "NOVEL work (find every attachment point, quote nothing, because nothing is broken).",
6
+ "",
7
+ "Two bodies rather than one prompt with a branch: the two say opposite things about the",
8
+ "single most consequential field -- brokenLine is REQUIRED in one and must be empty in the",
9
+ "other -- and a branching prompt hides which set of instructions an agent actually received."
10
+ ],
11
+ "description": "What the code-graph detective must converge on, by story kind: a causal site for a defect, or every attachment point for novel work.",
12
+ "id": "detective-prescription",
13
+ "seams": [
14
+ "code-graph-detective"
15
+ ],
16
+ "placeholders": [],
17
+ "version": 1,
18
+ "bodies": {
19
+ "defect": "CONVERGE FAST — HARD LIMIT: 6 tool calls total. This is not a suggestion.\nBy your 6th tool call you MUST stop querying and emit the JSON answer with your BEST current hypothesis. Exploring past 6 calls WITHOUT emitting the JSON means you FAIL and every bit of your investigation is thrown away — a best-guess fix site is infinitely better than no answer. If you are unsure, pick the single most likely file/function from what you have seen and emit it now; do NOT keep exploring to be \"sure\".\n1. First call: `explore` with the DOMAIN NOUNS only (drop symptom/presentation words like displayed/shown/email/confirmation/expected).\n2. Look at the top-ranked symbols. If the top hit's file only READS the wrong field (a mapper/sanitizer/display file), do ONE `callers` or `callees` (or one more `explore` toward the mechanism) to reach the code that COMPUTES/ASSIGNS it.\n3. As SOON as you identify a file whose function body actually computes/assigns the wrong value, STOP tracing and switch to prescribing the fix (step 4). Aim to finish tracing in 2-4 tool calls, never more than 6.\n4. PRESCRIBE THE MINIMAL FIX. This is the most important output. For the causal site:\n - Name the EXACT broken line/expression (e.g. `lineItem.id === discount.lineItemId`) and why it is wrong.\n - State the SMALLEST change that corrects it. Do NOT describe a re-architecture, a new abstraction, or a \"split/recalculate/add-a-field\" scheme unless the code genuinely has no simpler fix. Prefer a one-line/one-expression change.\n - LOCATE AN EXISTING HELPER instead of inventing new logic. Before proposing any new function, use `explore` (and `callers`/`callees`) to search for an already-present util/helper/parser in this repo that does the needed transform (e.g. a key parser, id normalizer, formatter). If one exists, your fix MUST name it (exact symbol + its import path) and reuse it. Writing novel code when a helper already exists is a defect.\n\n\nSHOW THE BROKEN CODE — \"brokenLine\" is REQUIRED and is machine-verified. Quote the EXACT source expression, copied verbatim from the file you name, that is wrong today. It is checked against that file's real contents: if what you quote is not in the file, your answer is rejected as ungrounded and you will be asked again. This is the difference between a diagnosis and a guess — a confident story about code that is not there reads exactly like a correct one until this check runs. If you cannot point at a real line that is wrong, you have not found the cause yet: go back to the tool and trace further.\n\n",
20
+ "novel": "CONVERGE FAST — HARD LIMIT: 6 tool calls total. This is not a suggestion.\nBy your 6th tool call you MUST stop querying and emit the JSON answer. A partial map of the attachment points is infinitely better than no answer.\n1. First call: `explore` with the DOMAIN NOUNS only (drop symptom/presentation words).\n2. NOTHING IS BROKEN HERE. This story asks for a capability that does not exist yet, so there is no wrong value to trace and no line to quote. Do not hunt for a cause — you will invent one.\n3. FIND EVERY PLACE THIS WORK MUST TOUCH. This is the most important output, and returning only ONE is the known failure of this step. A new capability almost never lands in a single file. Trace the SHAPE of it through this repository, in whatever terms this repository uses:\n - WHERE IT IS SET UP — the place the thing being enabled is created, configured or registered. Start here.\n - WHAT CARRIES IT — anything between that setup and the code that uses it: a shared module, a wrapper, an app-wide registration, a passed-down value. There may be none; there may be several.\n - EVERYWHERE IT IS USED — every place that reads the affected data or must react when it changes. There is usually MORE THAN ONE. Name them all.\n Do not force this repository into a shape it does not have, and do not skip a place because it has no obvious name. Describe each site in the vocabulary the codebase itself uses, which you have seen in the tool output — not in the vocabulary of some other project's architecture.\n4. COVER THE ACCEPTANCE CRITERIA. Read them again and check your site list against them: every criterion describing observable behaviour needs a site where that behaviour becomes possible. A criterion with no corresponding site means your map is incomplete — go back and find it.\n5. NAME WHAT TO REUSE at each site — whatever already exists there that the implementation should build on rather than duplicating. Use `explore`/`callers`/`callees` to find it; you cannot reuse what you have not found.\n6. `brokenLine` is NOT required for this story and must be left \"\" — there is no broken expression to quote.\n7. DO NOT INVENT A PATH OR A SYMBOL. Your grounding here is provenance, not a quoted line: every file and symbol you name must have been returned to you by a tool. If you believe something exists and the tools did not show it, PROVE it with ripgrep-search.sh before naming it, or report it absent.\n\n"
21
+ }
22
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "$why": [
3
+ "A FRAGMENT prepended to the detective prompt on a retry, 2026-08-16.",
4
+ "",
5
+ "A retry that repeats the original instruction gets the original answer. This says what",
6
+ "went wrong — no JSON array came back, probably because a write tool was called — which is",
7
+ "the only new information the second attempt has.",
8
+ "",
9
+ "It is a template like any other prompt text. Retry fragments are the easiest thing to",
10
+ "leave embedded, precisely because they are short and feel like plumbing."
11
+ ],
12
+ "body": "\\n\\nRETRY — your previous reply contained NO JSON array (you may have called a write tool). Emit ONLY the JSON array as text in THIS reply now. Do NOT call WriteFile or write to any file.",
13
+ "description": "Prepended to the detective prompt when its previous reply contained no JSON array.",
14
+ "id": "detective-retry-note",
15
+ "placeholders": [],
16
+ "version": 1,
17
+ "seams": [
18
+ "code-graph-detective"
19
+ ]
20
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "$why": [
3
+ "Operator, 2026-10-01 (a story spanning a shared library and the codelines that consume it): shared",
4
+ "changes MUST be treated differently, the run must mirror what a developer faces, and it is the",
5
+ "detective's judgement, not engine rules. The spec said the consumers needed no edit because their",
6
+ "declared range 'picks it up'; the library was a major version past every consumer's range.",
7
+ "Appended to the detective's prescription only when its story spans more than one codeline, so a",
8
+ "story confined to one codeline is asked exactly what it was asked before.",
9
+ "Operator, 2026-10-06: a consumer's declared range is never changed by a story ('avoid package.json upgrades in this change'; a range may be locked for a reason); the provider ships the change on a release line inside each consumer's range."
10
+ ],
11
+ "description": "Composed into the code-graph detective's prescription for a story that spans codelines: say whether a fix site is shared between them, and whether each consumer's declared range takes the change.",
12
+ "id": "detective-shared-package",
13
+ "seams": [
14
+ "code-graph-detective"
15
+ ],
16
+ "placeholders": [
17
+ "__CODELINE_PACKAGES__",
18
+ "__OTHER_CODELINES__",
19
+ "__SIBLING_SHARED__",
20
+ "__THIS_CODELINE__"
21
+ ],
22
+ "mayBeEmpty": [
23
+ "__CODELINE_PACKAGES__",
24
+ "__SIBLING_SHARED__"
25
+ ],
26
+ "version": 2,
27
+ "body": "\nTHIS STORY SPANS CODELINES. You are investigating codeline \"__THIS_CODELINE__\"; the same story is also being worked in: __OTHER_CODELINES__.\n__CODELINE_PACKAGES__\nSAY WHETHER A FIX SITE IS SHARED — add \"shared\" to a fix site when the change lives in, or depends on a change to, a package that one of these codelines PROVIDES and another CONSUMES. A change to a shared package is not finished when its own repository builds: every consumer receives it only through the version range it declares, so a change that ships in a version outside a consumer's range never reaches that consumer, however correct it is. Read the facts, do not assume them: this codeline's own manifest says what it provides (its name and version) or which range of a package it consumes, and what is actually installed. Where PACKAGE FACTS are given above, they are read from the manifests and are authoritative: shipsInVersion is the providing codeline's version there unless this change must ship in a different one, and a consumer judges receivesChange by comparing its declared range with it. Where they are not given, the codeline that PROVIDES the package states shipsInVersion from its own manifest; a consumer never assumes its range will take the change.\n\n \"shared\": {\"package\":\"<the package name, as its manifest declares it>\",\"providedBy\":\"<the codeline that provides it>\",\"shipsInVersion\":\"<the version the provider's change will ship in, read from the provider's own manifest; empty when you cannot read it>\",\"consumers\":[{\"codeline\":\"<a codeline that consumes it>\",\"declaredRange\":\"<the range that codeline's manifest declares, or \\\"unknown\\\" when you cannot read it>\",\"receivesChange\":<true if that range takes the version this change ships in, false if it does not, null if you cannot tell>}],\"note\":\"<one line: what a consumer must do to build and test against this change>\"}\n\nOmit \"shared\" on a site that touches nothing another of these codelines provides or consumes — that is the common case. A consumer's declared range of a shared package is NEVER changed by this story: moving it is that consumer's own migration (across a major version it is a breaking upgrade), not part of this change. If a consumer cannot receive the change through its declared range, say so with receivesChange:false and name the remedy in the PROVIDER: a fix site that also ships the change on a release line inside that consumer's range — cut from the newest release the range already takes, shipping as the next version on that line — and state that version as the consumer's shipsInVersion. Never name a consumer's manifest entry as a fix site. A consumer whose only remaining change was its range has no manifest edit; describe what it still needs in its own code, or that it receives the change unedited once the in-range release is installed.\n__SIBLING_SHARED__"
28
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "$why": [
3
+ "Moved out of lib/codeline-discovery.js on 2026-08-16. It was missed by the prose guard for",
4
+ "the same reason every earlier sweep under-reported: the guard matches second-person and",
5
+ "imperative openers, and this prompt opens with a heading. The count it reports is a floor.",
6
+ "",
7
+ "This agent decides which ticket words carry selection signal before the codelines are",
8
+ "scored, and it ABORTS the run when it fails -- so its wording is load-bearing for step 1",
9
+ "and had no reviewable home."
10
+ ],
11
+ "description": "Derives, per ticket, which terms discriminate between candidate repositories and which are filler.",
12
+ "id": "discovery-vocabulary",
13
+ "seams": [
14
+ "codeline-discovery"
15
+ ],
16
+ "placeholders": [
17
+ "__PERSONA__",
18
+ "__TICKET_BLOCK__",
19
+ "__CANDIDATE_BLOCK__"
20
+ ],
21
+ "version": 1,
22
+ "body": "__PERSONA__TICKETS UNDER DISCOVERY\n__TICKET_BLOCK__\n\nCANDIDATE REPOSITORIES IN THE CODELINE ROOT\n__CANDIDATE_BLOCK__\n\nTASK\nThe ticket text above is about to be broken into terms and searched against the code of every\ncandidate repository, to decide which one gets modified. Some of those terms cannot separate\none candidate from another: grammatical filler, process and workflow words, and words that\ndescribe the request rather than the software.\n\nReturn the vocabulary as JSON inside <DISCOVERY_VOCABULARY></DISCOVERY_VOCABULARY>:\n\n<DISCOVERY_VOCABULARY>\n{\"blacklist\":[{\"term\":\"<a lowercase term from the ticket text that cannot discriminate between these candidates>\",\"reason\":\"<why it carries no selection signal here>\"}],\n \"whitelist\":[{\"term\":\"<a term that must survive filtering because it names something in the software>\",\"reason\":\"<why>\"}]}\n</DISCOVERY_VOCABULARY>\n\nRULES\n- Every term must appear in the ticket text above. Do not invent vocabulary.\n- Judge against THESE candidates. A word that is filler on another project may be the product\n name here; a word that names a component of one of the candidates above is never filler.\n- An identifier, symbol, filename, endpoint, product or component name is NEVER blacklisted,\n even when it is rare or looks like an abbreviation. Whitelist it if in doubt.\n- The blacklist may not be empty: if the ticket really contains no filler at all, say so by\n returning the single least informative term with that reason.\n- No prose outside the tags."
23
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "$why": [
3
+ "Moved out of run-agent-orchestration.sh on 2026-08-16.",
4
+ "",
5
+ "The browser E2E routing check for one route."
6
+ ],
7
+ "description": "Checks one route renders and behaves in a browser E2E pass.",
8
+ "seams": [
9
+ "qa-gate:e2e"
10
+ ],
11
+ "id": "e2e-route-check",
12
+ "version": 1,
13
+ "body": "You are running as __ROUTE__ inside Step 4.6 Browser E2E routing checks.\nPhase: __PHASE_ID__\nStory: __STORY_ID__\nStory title: __STORY_TITLE__\nRoute reason: __ROUTE_REASON__\nComplexity score: __ROUTE_SCORE__\n\nReturn strict JSON only:\n{\n \"agent\": \"__ROUTE__\",\n \"storyId\": \"__STORY_ID__\",\n \"phase\": \"__PHASE_ID__\",\n \"verdict\": \"pass|warn|fail\",\n \"findings\": [{\"severity\": \"blocker|major|minor\", \"message\": \"...\", \"file\": \"...\", \"line\": 0}],\n \"summary\": \"...\"\n}",
14
+ "placeholders": [
15
+ "__ROUTE_REASON__",
16
+ "__STORY_TITLE__",
17
+ "__ROUTE_SCORE__",
18
+ "__PHASE_ID__",
19
+ "__STORY_ID__",
20
+ "__ROUTE__"
21
+ ]
22
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "$why": [
3
+ "Moved out of spec-mode-runner.js buildSurveyPrompt on 2026-08-15, first of the twenty",
4
+ "seams that still invoked a model from a prompt embedded in code.",
5
+ "",
6
+ "This prompt decides which codelines are in scope and which investigators get minted, so a",
7
+ "reworded sentence changes the roster and every stage that runs under it. The body was",
8
+ "extracted mechanically and pinned byte for byte by a golden capture taken before the move.",
9
+ "",
10
+ "The conditional SECTIONS — documents, declared dependencies — are computed by the caller",
11
+ "and arrive whole, heading included, or as an empty string. The template holds no logic:",
12
+ "a template that branches is a program, and it cannot be reviewed as prose."
13
+ ],
14
+ "body": "You are surveying an estate of repositories BEFORE its agent team is assembled.\n\nTHE WORK (real tickets from the tracker):\n__TICKET_BLOCK__\n\n__DOC_SECTION__\n__DEP_SECTION__\nTHE CODELINES IN SCOPE, and where each is checked out:\n__CODELINE_BLOCK__\n\nHOW TO LOOK — USE THE SYMBOL INDEX, NOT TEXT SEARCH.\n\nEvery codeline above is already indexed in CodeGraph. Use codegraph_query as your PRIMARY\ninstrument, and call it iteratively — 5-10 calls is normal. EVERY call takes a named `mode`\nplus that mode's own named field — there is no positional form:\n EVERY call names the codeline it is about — the tool answers from THAT repository, and a\n call that names none is refused when several are in scope, because answering from the\n wrong one returns another repository's symbols as though they were this one's.\n - codegraph_query(mode=\"explore\", codeline=\"<name>\", terms=\"<domain nouns from the ticket>\") — START HERE, per codeline\n - codegraph_query(mode=\"query\", codeline=\"<name>\", symbol=\"<SymbolName>\") — where a symbol is defined\n - codegraph_query(mode=\"callers\", codeline=\"<name>\", symbol=\"<SymbolName>\") — who calls it\n - codegraph_query(mode=\"callees\", codeline=\"<name>\", symbol=\"<SymbolName>\") — what it calls\n - codegraph_query(mode=\"show\", codeline=\"<name>\", file=\"<path>\") — read the real lines before\n quoting anything as evidence\n\nIf a call comes back with an error, READ IT — it names the field it wanted. Do NOT send the\nsame call again unchanged: the tool refuses an identical repeat, so a retry loop burns your\nbudget and returns nothing. If codegraph_query cannot be made to work at all, say so in your\nevidence AND fall back to read_file and list_files rather than reporting a codeline you never\nopened — a survey that examined nothing must never be the reason a team is assembled blind.\nIt returns real symbols, their definition sites, who calls them, and which have tests. That is\nthe question you are actually asking: where does this codeline wire the thing the ticket is\nabout. Text search cannot answer it and ranks a vendored copy of a package alongside the one\nline that initialises it.\n\nReserve 'search' for what a symbol index cannot hold — a config key, an environment variable\nname, a literal string. Then treat its result with suspicion:\n\n A SEARCH THAT RETURNS NOTHING IS NOT EVIDENCE THAT NOTHING IS THERE.\n\nOn 2026-08-08 this survey reported \"searched for seven patterns, all returned zero matches, no\nexisting infrastructure was found, meaning this is greenfield work\" about three codelines\nholding 243, 102 and 158 matching source files. The search tool was silently broken and every\ncall returned \"(no matches found)\". The reasoning was sound and the premise was false. If a\nsearch comes back empty, confirm with codegraph_query before concluding absence — and if the\ntwo disagree, say so in your evidence rather than picking one.\n\nYOUR JOB, and its limits:\n\n1. For EVERY codeline above, OPEN IT and decide whether this work reaches it. The ticket's\n labels and components are a claim, not evidence — they are frequently wrong about which\n repositories are involved, which is why you exist. Report what you actually looked at.\n\n2. \"I looked and this work does not reach this codeline\" is a VALUABLE answer. Report it as\n no_work_found, with the evidence. It is not the same as not having looked, and reporting\n the two as one is how an unexamined repository comes to read as a clean bill of health.\n\n3. Recommend the TEAM this estate needs, in two separate lists.\n - recommendedInvestigators: which codelines need their own investigator to READ them, and\n what each should concentrate on.\n - recommendedWriters: which codelines need an agent that WRITES the change, and what kind of\n work it must be able to build.\n Every estate with work to do needs at least one writer. A team that can only look at code\n cannot change it, and a roster of investigators leaves every story with nobody to implement.\n Keep both OUT of your findings: findings are what you saw, recommendations are about the team.\n Neither may name a fix site. \"this codeline needs someone who can write X\" is a\n recommendation; \"edit this file at this line\" is not yours to say, and is stripped if you\n write it.\n\nREPORT THE EXACT FILES YOU OPENED, in \"filesRead\". If you report a codeline as in_scope you\nmust name AT LEAST ONE FILE you opened in it: saying the work reaches a repository you did not\nread is an assertion, and an assertion of exactly that kind produced \"no existing\ninfrastructure, this is greenfield work\" about an estate with 243 matching source files.\nLooking and finding nothing is different, and is a valuable answer — report that as\nno_work_found with what you read. A directory tells a later reader almost\nnothing — src/context/ exists in most codelines — and a claim about it cannot be checked. A\nfile path can be verified, and a brief built on one is grounded. Report what you read even\nwhere you conclude the work does not reach that codeline.\n\nWHAT YOU MUST NOT DO. You are not fixing anything and you are not choosing files to change.\nDo not say which file to edit, which function to patch, or what the change should be. Naming a\nfile as something you READ is evidence and is wanted; naming one as the place to fix is a\ndecision that is not yours. Each codeline gets its own investigator working inside that\nrepository, and it decides. A fix site you supply for a repository you swept from the outside\nis how one codeline's file ends up in another's work — so report what you saw, state where to\nlook, and let the investigator look.\n\nOne entry in \"codelines\" for EVERY codeline listed in scope. Everything you want to say goes\ninside these fields — a prose report outside the answer block stated below is discarded unread, however good it is.",
15
+ "description": "Survey an estate of repositories before its agent team is assembled.",
16
+ "id": "estate-survey",
17
+ "placeholders": [
18
+ "__CODELINE_BLOCK__",
19
+ "__DEP_SECTION__",
20
+ "__DOC_SECTION__",
21
+ "__TICKET_BLOCK__"
22
+ ],
23
+ "version": 1,
24
+ "seams": [
25
+ "estate-survey"
26
+ ],
27
+ "$mayBeEmptyWhy": "A survey may run with no referenced documents and against a codeline whose manifest declares nothing. Both are real states, and the section reads correctly as absent — unlike a brief or a tool grant, where empty means the value never arrived.",
28
+ "mayBeEmpty": [
29
+ "__DOC_SECTION__",
30
+ "__DEP_SECTION__"
31
+ ]
32
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "$why": [
3
+ "2026-09-28. The estimation application's assessment of a ticket (EPAM_ESTIMATION_MANIFEST,",
4
+ "lib/handlers/estimation-manifest.js) reaches six brownfield agents. The FACTS are the same for",
5
+ "all of them; what they are FOR is the reader's, so each consumer has its own body. The same",
6
+ "rule binds every body: this is evidence gathered before the work, to be verified in the code,",
7
+ "never an instruction — and work the assessment marks as outside the estimate stays outside",
8
+ "unless the ticket's own acceptance criteria require it (the scope-creep guard: the AMSD-2974",
9
+ "assessment lists five stand-alone implementations its split leaves out)."
10
+ ],
11
+ "description": "Framing of the estimation application's per-ticket assessment, one body per consuming agent.",
12
+ "id": "estimation-assessment",
13
+ "placeholders": [
14
+ "__TICKET__",
15
+ "__ASSESSMENT__"
16
+ ],
17
+ "version": 2,
18
+ "bodies": {
19
+ "spec-agent": "\n## Estimation assessment for __TICKET__ (evidence, gathered before this work)\n\nThe estimation application read this ticket, its attachments and the codeline, and recorded what it found. Use it to make the verification criteria concrete — each gap it confirms in the implementation is something a criterion should prove fixed. It is evidence, not the requirement: the ticket's acceptance criteria remain the requirement. Work the assessment places outside the estimate (for example a slice its recommended split excludes) is OUT OF SCOPE unless an acceptance criterion requires it; do not write criteria for it.\n\n__ASSESSMENT__\n",
20
+ "code-graph-detective": "\n## Estimation assessment for __TICKET__ (where the estimator found the work)\n\nThe estimation application read the codeline for this ticket. It names components, call sites, overrides and findings — use them as leads for locating the fix site, and CONFIRM each in the code before relying on it: files move, and the assessment may predate them. Locations it places outside the estimate are out of scope for this ticket.\n\nAccount for every in-scope location the assessment names in this codeline, in the answer you return: a fix site you confirmed in the code (changeRequired true, with the fix), or one you refuted (changeRequired false, the evidence in its reason — what you read and why it needs no change here). Never silently drop a lead: an unanswered lead is work nobody will do.\n\n__ASSESSMENT__\n",
21
+ "cpa-inference": "\n## Estimation assessment for __TICKET__ (independent sizing, gathered before this work)\n\nThe estimation application sized this ticket and recommended how to split it. Weigh its findings and its split when judging scope and effort; where your analysis of the code disagrees, say so and why. Slices it places outside the estimate are OUT OF SCOPE for this ticket unless an acceptance criterion requires them.\n\n__ASSESSMENT__\n",
22
+ "story-writer": "\n## Estimation assessment for __TICKET__ (findings in the code, gathered before this work)\n\nThe estimation application found these defects and risks in the code this ticket touches. Treat each in-scope finding as a target your change must address, and verify it in the source first — do not take a line number or a name on trust. Do NOT implement work the assessment places outside the estimate (a slice its recommended split excludes) unless the acceptance criteria require it.\n\n__ASSESSMENT__\n",
23
+ "repro-test-writer": "\n## Estimation assessment for __TICKET__ (the defects the estimator confirmed)\n\nThe estimation application confirmed these defects in the code. Your reproducing test should prove the in-scope ones — fail on the baseline, pass with the fix. Do not write tests for work the assessment places outside the estimate.\n\n__ASSESSMENT__\n",
24
+ "team-lead-review": "\n## Estimation assessment for __TICKET__ (what the change was expected to address)\n\nThe estimation application found these defects before the work began. Judge the diff against the in-scope findings: an in-scope finding the change leaves unaddressed is a gap to report. A change that implements work the assessment places outside the estimate (a slice its recommended split excludes), without an acceptance criterion requiring it, is scope creep — report it.\n\n__ASSESSMENT__\n"
25
+ }
26
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "$why": [
3
+ "The writer's half of the detective's 'shared' finding (see detective-shared-package). A developer",
4
+ "changing a shared package and a consumer at once builds and tests the consumer against the",
5
+ "package's working copy, and saves none of that redirection: it is how they test, not what they",
6
+ "ship. The location is RELATIVE to this codeline (operator, 2026-10-01: no absolute paths in a",
7
+ "prompt). Rendered by the fix-plan producer only when a site of this story carries 'shared'.",
8
+ "Operator, 2026-10-06: a consumer's declared range is never changed by a story ('avoid package.json upgrades in this change'; a range may be locked for a reason); the provider ships the change on a release line inside each consumer's range."
9
+ ],
10
+ "description": "Appended to a writer's fix plan when the detective reported a shared fix site: what is shared, where each sibling codeline's working copy is, and how to build and test against it without saving the redirection.",
11
+ "id": "fix-plan-shared",
12
+ "seams": [],
13
+ "placeholders": [
14
+ "__SHARED_SITES__",
15
+ "__SIBLING_LOCATIONS__"
16
+ ],
17
+ "version": 2,
18
+ "body": "\n\nSHARED WITH OTHER CODELINES OF THIS STORY — the investigation found these fix sites are shared:\n__SHARED_SITES__\nThe other codelines' working copies, relative to this codeline's root:\n__SIBLING_LOCATIONS__\nWhere this codeline consumes a package another codeline provides, that codeline's current working copy (with this run's changes in it) is already installed in this codeline's dependencies by the pipeline, without being saved to the manifest: build and test as they are, and do not change how the dependency resolves. Never edit a consumer's declared range of a shared package — not here, not in any codeline: where a consumer's range does not take the version the change ships in, the providing codeline also ships the change on a release line inside that range (cut from the newest release the range takes), and the consumer's manifest stays exactly as it is. Where this codeline provides the package, its change is not finished until every consumer above can receive it through the range that consumer ALREADY declares — on each release line that range requires; say in your final message which release line serves which consumer."
19
+ }