thincoder 0.12.35 → 0.12.36

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thincoder",
3
- "version": "0.12.35",
3
+ "version": "0.12.36",
4
4
  "description": "Thin coding agent - zero dependencies, no build step, Node.js native. Sharp code, zero bloat.",
5
5
  "keywords": [
6
6
  "ai",
@@ -185,13 +185,27 @@ export function buildAdvisorUserMessage(agent, prior, reviewType, designToken =
185
185
  } catch { /* file doesn't exist — skip */ }
186
186
  }
187
187
 
188
+ // Document map (docs/design/README.md) — inject when the discovered
189
+ // project root has one: the reviewer checks document ownership against it
190
+ // (a change for an existing section must amend that section's document,
191
+ // not spawn a new file for it). Absent map → skip (nothing to check against).
192
+ try {
193
+ const mapPath = resolve(guideRoot ?? agent.cwd, "docs", "design", "README.md")
194
+ if (existsSync(mapPath)) {
195
+ parts.push("## Document Map")
196
+ parts.push("The document map below registers which document files exist per section. Use it for the Document ownership criterion: a change for an existing section must amend that section's document, not create a new file.")
197
+ parts.push(readFileSync(mapPath, "utf8"))
198
+ parts.push("")
199
+ }
200
+ } catch { /* file doesn't exist or is unreadable — skip */ }
201
+
188
202
  parts.push("## Instructions")
189
203
  if (docList.length > 0) {
190
204
  parts.push("1. Read every document in the Documents to Review list in full — review ONLY those files. Read METHODOLOGY.md to understand the project's standards.")
191
205
  } else {
192
206
  parts.push("1. Read the design document fully. Read METHODOLOGY.md to understand the project's standards.")
193
207
  }
194
- parts.push("2. Review against: completeness (all requirements covered?), feasibility (can this be built?), clarity (specific enough?), acceptance criteria (verifiable?), scope (appropriate?).")
208
+ parts.push("2. Review against: completeness (all requirements covered?), feasibility (can this be built?), methodology compliance (does it follow the project's METHODOLOGY.md?), clarity (specific enough?), acceptance criteria (verifiable?), scope (appropriate?).")
195
209
  parts.push("3. If the ## Project Guide (AGENTS.md) section above is present, also check requirement fit: does the design match what the requirements documents it points to actually ask for?")
196
210
  parts.push("4. Do NOT run git diff or look for code changes — there are none at this stage.")
197
211
  parts.push("5. If you find issues, produce your review table with the format: | # | Category | Severity | Issue | Suggestion |. If the design passes, no table is needed.")
package/src/advisor.mjs CHANGED
@@ -72,14 +72,11 @@ const ADVISOR_ROUND1 = loadPrompt("advisor-round1.md", "advisor-round1.md")
72
72
  // buildAdvisorSystemPrompt when _advisorRound > 0.
73
73
  const ADVISOR_ROUND2 = loadPrompt("advisor-round2.md", "advisor-round2.md")
74
74
  const ADVISOR_ROUND3 = loadPrompt("advisor-round3.md", "advisor-round3.md")
75
- // Fallback when advisor-design.md is missing keep in sync with the real
76
- // file (table format + workflow steps).
77
- const ADVISOR_DESIGN_FALLBACK = `You are an independent design reviewer for an engineering-mode project. Review the design document in the changes below. Evaluate: completeness, feasibility, clarity, scope, acceptance criteria. Read METHODOLOGY.md if provided. Produce a review table with | # | Category | Severity | Issue | Suggestion | format.`
78
- let ADVISOR_DESIGN = ""
79
- // Design review is OPTIONAL (engineering mode only) — silent fallback to the
80
- // in-code constant is intentional, unlike the mandatory round prompts which
81
- // must exist for every review (loadPrompt throws a descriptive error there).
82
- try { ADVISOR_DESIGN = readFileSync(join(__dirname, "prompts", "advisor-design.md"), "utf8") } catch { /* fallback below */ }
75
+ // Design-review prompthard-loaded like the round prompts (decision
76
+ // 2026-08-21): a missing file means a broken installation, and silently
77
+ // degrading to a lesser in-code prompt would quietly strip the approval-signal
78
+ // and citation rules, disabling design approval entirely. loadPrompt throws.
79
+ const ADVISOR_DESIGN = loadPrompt("advisor-design.md", "advisor-design.md")
83
80
 
84
81
  // ────────────────────────────────────────
85
82
  // System prompt building
@@ -109,7 +106,7 @@ export function buildAdvisorSystemPrompt(agent, prior, reviewType) {
109
106
  // approval token); rounds 2+ converge like code reviews (verify agent fix claims).
110
107
  if (reviewType === "design") {
111
108
  if (!hasPrior) {
112
- return ADVISOR_DESIGN || ADVISOR_DESIGN_FALLBACK
109
+ return ADVISOR_DESIGN
113
110
  }
114
111
  const round = (agent._advisorRound || 0) + 1
115
112
  if (round === 2) return ADVISOR_ROUND2
@@ -12,6 +12,7 @@ Evaluate the design against these dimensions:
12
12
  4. **Clarity** — Is the design specific enough to implement? Are the affected files identified?
13
13
  5. **Acceptance criteria** — Are they verifiable? Do they cover normal paths, edge cases, and error conditions?
14
14
  6. **Scope** — Is the scope appropriate? Are there opportunities to simplify? Is there scope creep?
15
+ 7. **Document ownership** — Does the change amend the design document that already owns its topic (per the document map in `docs/design/README.md`), or does it fragment by creating a new file for an existing section? Does the wording duplicate or contradict existing documents?
15
16
 
16
17
  ## Output Format
17
18
 
@@ -27,6 +28,14 @@ Severity levels:
27
28
  - 🟡 Advisory — design could be improved; NOT a blocker for approval
28
29
  - 🔵 Note — optional observation; NOT a blocker
29
30
 
31
+ Document ownership severity:
32
+ - Wording that CONTRADICTS an existing document (same mechanism described differently in two places) → 🔴
33
+ - Creating a new file for an existing section, or duplicating a description that already exists elsewhere → 🟡
34
+
35
+ ## Citation Discipline
36
+
37
+ When you cite design-document text, use the exact `file:line` format (e.g. `docs/design/AGENT-LOOP.md:180`) — host-side verification will check the citation against the current disk state. If you have not read/verified the cited content, mark it `unverified` instead of presenting it as fact.
38
+
30
39
  ## Approval Signal
31
40
 
32
41
  The user message contains an exact token in an `## Approval Signal` section (format `[DESIGN-TOKEN:...]`).
@@ -8,6 +8,7 @@ Programming is collaborative labor between you and the human. The human decides
8
8
 
9
9
  **How you work — before you write any code:**
10
10
  - **Read design docs first.** Use `doc_search` to find relevant design docs, AGENTS.md, and architecture decisions. Code without design context is guesswork. If docs conflict with code, docs are right. If the user's instruction conflicts with the docs, tell the user first — discuss, update the docs, then code.
11
+ - **Document ownership — find the doc that owns the topic before writing.** Before writing to `docs/design/`, check the `docs/design/README.md` document map (no map → check AGENTS.md and the docs directory) to locate the document that owns the topic — if it exists, update it; never create a new file for an existing section. Create a new file only when no section owns the topic, and register it in the map. Describe each mechanism in detail in exactly ONE place (the authoritative source); other documents reference it, never copy it.
11
12
  - **Check existing code.** Search for existing functions, helpers, patterns before writing new ones. Duplicates are technical debt.
12
13
  - **Understand intent.** Ask why this change is needed — the "why" reveals scope the literal request hides.
13
14
  - **Confirm understanding.** State what you believe the user asked for and what you plan to deliver, including the most important acceptance criteria. Wait for confirmation. No task is too small — a wrong assumption always costs more than the round-trip. Once confirmed, deliver exactly what was agreed — no simplifying, no substituting, no taking shortcuts after the fact. Simplifying a confirmed requirement frustrates the user and wastes time; they will just tell you to do it right anyway.