@longtable/checkpoints 0.1.38 → 0.1.40

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.
@@ -3,8 +3,8 @@ const RULES = [
3
3
  family: "meta_decision",
4
4
  checkpointKey: "meta_decision",
5
5
  stage: "problem_framing",
6
- mode: "commit",
7
- level: "adaptive_required",
6
+ mode: "review",
7
+ level: "recommended",
8
8
  cues: [
9
9
  /\brename\b/i,
10
10
  /\bnaming\b/i,
@@ -15,7 +15,7 @@ const RULES = [
15
15
  /\bmake .*authoritative\b/i,
16
16
  /이름|명명|리드미|체크포인트 정책|플랫폼 용어|제품 언어/
17
17
  ],
18
- rationale: "Platform language and checkpoint policy shape future LongTable behavior."
18
+ rationale: "Platform language and checkpoint policy should be discussed without creating a research-state checkpoint."
19
19
  },
20
20
  {
21
21
  family: "submission",
@@ -156,7 +156,7 @@ const RULES = [
156
156
  checkpointKey: "knowledge_gap_probe",
157
157
  stage: "problem_framing",
158
158
  mode: "explore",
159
- level: "adaptive_required",
159
+ level: "recommended",
160
160
  cues: [
161
161
  /\bknowledge gap\b/i,
162
162
  /\bgap in (my|our|the) knowledge\b/i,
@@ -171,14 +171,14 @@ const RULES = [
171
171
  /\bhelp me narrow\b/i,
172
172
  /지식의 공백|지식 공백|모르겠|불확실|놓치고 있|빠뜨리고 있/
173
173
  ],
174
- rationale: "A named knowledge gap should be surfaced before LongTable narrows or closes the problem."
174
+ rationale: "A named knowledge gap should be surfaced as response-only guidance unless a research commitment is being made."
175
175
  },
176
176
  {
177
177
  family: "review",
178
178
  checkpointKey: "tacit_assumption_probe",
179
179
  stage: "problem_framing",
180
180
  mode: "review",
181
- level: "adaptive_required",
181
+ level: "recommended",
182
182
  cues: [
183
183
  /\btacit\b/i,
184
184
  /\bimplicit\b/i,
@@ -188,7 +188,7 @@ const RULES = [
188
188
  /\bhidden constraint\b/i,
189
189
  /암묵지|암묵적|전제|가정|사각지대|숨은 제약|암묵/
190
190
  ],
191
- rationale: "Tacit assumptions can silently shift research responsibility and need an explicit researcher-facing check."
191
+ rationale: "Tacit assumptions should be made visible without becoming a durable checkpoint unless they block a research commitment."
192
192
  },
193
193
  {
194
194
  family: "exploration",
@@ -275,12 +275,22 @@ function requiresQuestion(level, mode, family) {
275
275
  mode === "submit" ||
276
276
  family === "meta_decision");
277
277
  }
278
+ function looksLikeCommitmentCue(prompt) {
279
+ return /\b(final|finalize|commit|ship|submit|publish|freeze|settle|decide|lock|record|apply|incorporate)\b/i.test(prompt)
280
+ || /최종|확정|커밋|제출|투고|고정|결정|기록|반영/.test(prompt);
281
+ }
282
+ function ruleRequiresQuestionForPrompt(rule, prompt) {
283
+ if (rule.family === "commitment" && !looksLikeCommitmentCue(prompt)) {
284
+ return false;
285
+ }
286
+ return requiresQuestion(rule.level, rule.mode ?? "review", rule.family);
287
+ }
278
288
  function pickBestRule(prompt) {
279
289
  const candidates = RULES.map((rule) => ({ rule, matches: matchCues(prompt, rule) }))
280
290
  .filter((candidate) => candidate.matches.length > 0)
281
291
  .sort((a, b) => {
282
- const requiredDelta = Number(requiresQuestion(b.rule.level, b.rule.mode ?? "review", b.rule.family)) -
283
- Number(requiresQuestion(a.rule.level, a.rule.mode ?? "review", a.rule.family));
292
+ const requiredDelta = Number(ruleRequiresQuestionForPrompt(b.rule, prompt)) -
293
+ Number(ruleRequiresQuestionForPrompt(a.rule, prompt));
284
294
  if (requiredDelta !== 0)
285
295
  return requiredDelta;
286
296
  const genericDelta = Number(a.rule.checkpointKey === "research_question_freeze") -
@@ -332,15 +342,40 @@ function fallbackLevel(mode) {
332
342
  return "recommended";
333
343
  }
334
344
  }
345
+ function looksLikeProductOrToolingPrompt(prompt) {
346
+ return /\b(longlongtable|hook|checkpoint|mcp|agents?|skills?|ux|interface|setup|install|cli|npm|version|global|release|deploy|git|github|readme|docs?|documentation|workflow|package|router|autocomplete|simulation test)\b/i.test(prompt)
347
+ || /롱테이블|훅|체크포인트|에이전트|스킬|사용성|인터페이스|설치|세팅|글로벌|배포|버전|릴리즈|깃|깃허브|문서화된\s*절차|패키지|라우터|자동완성|시뮬레이션\s*테스트/.test(prompt);
348
+ }
335
349
  export function classifyCheckpointTrigger(prompt, options = {}) {
336
350
  const normalizedPrompt = prompt.trim();
351
+ if (looksLikeProductOrToolingPrompt(normalizedPrompt)) {
352
+ return {
353
+ signal: {
354
+ checkpointKey: options.checkpointKey ?? "product_runtime_guidance",
355
+ baseLevel: "recommended",
356
+ mode: options.preferredMode ?? options.fallbackMode ?? "review",
357
+ artifactStakes: options.artifactStakes ?? "private_note",
358
+ researchStage: options.researchStage ?? "problem_framing",
359
+ ...(options.unresolvedTensions ? { unresolvedTensions: options.unresolvedTensions } : {}),
360
+ ...(options.studyContract ? { studyContract: options.studyContract } : {})
361
+ },
362
+ family: "advisory",
363
+ confidence: "high",
364
+ matchedCues: ["product_tooling"],
365
+ requiresQuestionBeforeClosure: false,
366
+ advisoryOnly: true,
367
+ rationale: ["Product, tooling, and LongTable policy work should use response-only discussion unless the researcher explicitly records a research decision."]
368
+ };
369
+ }
337
370
  const best = pickBestRule(normalizedPrompt);
338
371
  const inferredMode = inferModeFromPlainCue(normalizedPrompt);
339
372
  const mode = options.preferredMode ?? best?.rule.mode ?? inferredMode ?? options.fallbackMode ?? "explore";
340
373
  const stage = options.researchStage ?? best?.rule.stage ?? fallbackStage(mode);
341
374
  const stakes = options.artifactStakes ?? best?.rule.stakes ?? fallbackStakes(mode);
342
- const level = best?.rule.level ?? fallbackLevel(mode);
343
375
  const family = best?.rule.family ?? (mode === "explore" ? "exploration" : "advisory");
376
+ const level = family === "commitment" && !looksLikeCommitmentCue(normalizedPrompt)
377
+ ? "recommended"
378
+ : best?.rule.level ?? fallbackLevel(mode);
344
379
  const matchedCues = best?.matches ?? [];
345
380
  const checkpointKey = options.checkpointKey ?? best?.rule.checkpointKey ?? `${mode}_runtime_guidance`;
346
381
  const rationale = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@longtable/checkpoints",
3
- "version": "0.1.38",
3
+ "version": "0.1.40",
4
4
  "private": false,
5
5
  "description": "Checkpoint policy engine for LongTable",
6
6
  "type": "module",
@@ -21,7 +21,7 @@
21
21
  "typecheck": "tsc -p tsconfig.json --noEmit"
22
22
  },
23
23
  "dependencies": {
24
- "@longtable/core": "0.1.38"
24
+ "@longtable/core": "0.1.40"
25
25
  },
26
26
  "devDependencies": {
27
27
  "typescript": "^5.6.0"