minimal-vibe-coding-kit 0.5.0 → 0.5.1
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/.agents/skills/tutien/SKILL.md +36 -13
- package/.agents/skills/tutien/references/adaptive-response.md +68 -0
- package/.agents/skills/tutien/references/lore-sources.md +28 -0
- package/.agents/skills/tutien/references/privacy.md +13 -1
- package/.agents/skills/tutien/references/schema.md +32 -1
- package/.agents/skills/tutien/references/story-system.md +176 -0
- package/.agents/skills/tutien/references/vi-style-guide.md +89 -0
- package/.agents/skills/tutien/references/voice-and-mode.md +23 -8
- package/.agents/skills/tutien/scripts/catalog.mjs +17 -17
- package/.agents/skills/tutien/scripts/classify.mjs +64 -37
- package/.agents/skills/tutien/scripts/command.mjs +40 -21
- package/.agents/skills/tutien/scripts/project-profile.mjs +202 -0
- package/.agents/skills/tutien/scripts/render-report.mjs +128 -72
- package/.agents/skills/tutien/scripts/response-brief.mjs +103 -0
- package/.agents/skills/tutien/scripts/run-tutien.mjs +141 -63
- package/.agents/skills/tutien/scripts/story-ledger.mjs +241 -0
- package/.agents/skills/tutien/scripts/villains.mjs +14 -14
- package/.claude/skills/tutien/SKILL.md +36 -13
- package/.claude/skills/tutien/references/adaptive-response.md +68 -0
- package/.claude/skills/tutien/references/lore-sources.md +28 -0
- package/.claude/skills/tutien/references/privacy.md +13 -1
- package/.claude/skills/tutien/references/schema.md +32 -1
- package/.claude/skills/tutien/references/story-system.md +176 -0
- package/.claude/skills/tutien/references/vi-style-guide.md +89 -0
- package/.claude/skills/tutien/references/voice-and-mode.md +23 -8
- package/.claude/skills/tutien/scripts/catalog.mjs +17 -17
- package/.claude/skills/tutien/scripts/classify.mjs +64 -37
- package/.claude/skills/tutien/scripts/command.mjs +40 -21
- package/.claude/skills/tutien/scripts/project-profile.mjs +202 -0
- package/.claude/skills/tutien/scripts/render-report.mjs +128 -72
- package/.claude/skills/tutien/scripts/response-brief.mjs +103 -0
- package/.claude/skills/tutien/scripts/run-tutien.mjs +141 -63
- package/.claude/skills/tutien/scripts/story-ledger.mjs +241 -0
- package/.claude/skills/tutien/scripts/villains.mjs +14 -14
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor/skills/tutien/SKILL.md +36 -13
- package/.cursor/skills/tutien/references/adaptive-response.md +68 -0
- package/.cursor/skills/tutien/references/lore-sources.md +28 -0
- package/.cursor/skills/tutien/references/privacy.md +13 -1
- package/.cursor/skills/tutien/references/schema.md +32 -1
- package/.cursor/skills/tutien/references/story-system.md +176 -0
- package/.cursor/skills/tutien/references/vi-style-guide.md +89 -0
- package/.cursor/skills/tutien/references/voice-and-mode.md +23 -8
- package/.cursor/skills/tutien/scripts/catalog.mjs +17 -17
- package/.cursor/skills/tutien/scripts/classify.mjs +64 -37
- package/.cursor/skills/tutien/scripts/command.mjs +40 -21
- package/.cursor/skills/tutien/scripts/project-profile.mjs +202 -0
- package/.cursor/skills/tutien/scripts/render-report.mjs +128 -72
- package/.cursor/skills/tutien/scripts/response-brief.mjs +103 -0
- package/.cursor/skills/tutien/scripts/run-tutien.mjs +141 -63
- package/.cursor/skills/tutien/scripts/story-ledger.mjs +241 -0
- package/.cursor/skills/tutien/scripts/villains.mjs +14 -14
- package/.grok/skills/tutien/SKILL.md +36 -13
- package/.grok/skills/tutien/references/adaptive-response.md +68 -0
- package/.grok/skills/tutien/references/lore-sources.md +28 -0
- package/.grok/skills/tutien/references/privacy.md +13 -1
- package/.grok/skills/tutien/references/schema.md +32 -1
- package/.grok/skills/tutien/references/story-system.md +176 -0
- package/.grok/skills/tutien/references/vi-style-guide.md +89 -0
- package/.grok/skills/tutien/references/voice-and-mode.md +23 -8
- package/.grok/skills/tutien/scripts/catalog.mjs +17 -17
- package/.grok/skills/tutien/scripts/classify.mjs +64 -37
- package/.grok/skills/tutien/scripts/command.mjs +40 -21
- package/.grok/skills/tutien/scripts/project-profile.mjs +202 -0
- package/.grok/skills/tutien/scripts/render-report.mjs +128 -72
- package/.grok/skills/tutien/scripts/response-brief.mjs +103 -0
- package/.grok/skills/tutien/scripts/run-tutien.mjs +141 -63
- package/.grok/skills/tutien/scripts/story-ledger.mjs +241 -0
- package/.grok/skills/tutien/scripts/villains.mjs +14 -14
- package/.vibekit/skills/tutien/SKILL.md +36 -13
- package/.vibekit/skills/tutien/references/adaptive-response.md +68 -0
- package/.vibekit/skills/tutien/references/lore-sources.md +28 -0
- package/.vibekit/skills/tutien/references/privacy.md +13 -1
- package/.vibekit/skills/tutien/references/schema.md +32 -1
- package/.vibekit/skills/tutien/references/story-system.md +176 -0
- package/.vibekit/skills/tutien/references/vi-style-guide.md +89 -0
- package/.vibekit/skills/tutien/references/voice-and-mode.md +23 -8
- package/.vibekit/skills/tutien/scripts/catalog.mjs +17 -17
- package/.vibekit/skills/tutien/scripts/classify.mjs +64 -37
- package/.vibekit/skills/tutien/scripts/command.mjs +40 -21
- package/.vibekit/skills/tutien/scripts/project-profile.mjs +202 -0
- package/.vibekit/skills/tutien/scripts/render-report.mjs +128 -72
- package/.vibekit/skills/tutien/scripts/response-brief.mjs +103 -0
- package/.vibekit/skills/tutien/scripts/run-tutien.mjs +141 -63
- package/.vibekit/skills/tutien/scripts/story-ledger.mjs +241 -0
- package/.vibekit/skills/tutien/scripts/villains.mjs +14 -14
- package/CHANGELOG.md +22 -1
- package/README.md +5 -3
- package/docs/README.vi.md +5 -3
- package/docs/README.zh-CN.md +5 -3
- package/package.json +2 -2
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Deterministic storage helpers for the agent-authored living chronicle.
|
|
3
|
+
// This module never generates story prose. It only builds an aggregate-only
|
|
4
|
+
// evidence packet and validates the plot/chapter ledger written by the agent.
|
|
5
|
+
|
|
6
|
+
import crypto from 'node:crypto';
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import process from 'node:process';
|
|
10
|
+
import { fileURLToPath } from 'node:url';
|
|
11
|
+
|
|
12
|
+
export const STORY_SCHEMA = 1;
|
|
13
|
+
export const STORY_CONTEXT_SCHEMA = 'tutien-story-context-v1';
|
|
14
|
+
export const STORY_STATE_SCHEMA = 'tutien-story-state-v1';
|
|
15
|
+
export const STORY_CHAPTER_SCHEMA = 'tutien-story-chapter-v1';
|
|
16
|
+
|
|
17
|
+
const sha16 = (value) => crypto.createHash('sha256').update(String(value)).digest('hex').slice(0, 16);
|
|
18
|
+
|
|
19
|
+
export function storyPaths(root = process.cwd()) {
|
|
20
|
+
const base = path.join(path.resolve(root), '.vibekit', 'reports', 'tutien', 'story');
|
|
21
|
+
return {
|
|
22
|
+
base,
|
|
23
|
+
plot: path.join(base, 'plot.md'),
|
|
24
|
+
state: path.join(base, 'story-state.json'),
|
|
25
|
+
context: path.join(base, 'latest-context.json'),
|
|
26
|
+
chapters: path.join(base, 'chapters')
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Preserve letters from every language, including Han characters. Latin
|
|
31
|
+
// scripts are normalized so Vietnamese titles remain readable in filenames.
|
|
32
|
+
export function slugifyChapterTitle(title) {
|
|
33
|
+
const raw = String(title ?? '').trim();
|
|
34
|
+
if (!raw) throw new Error('chapter title is required');
|
|
35
|
+
const slug = raw
|
|
36
|
+
.normalize('NFD')
|
|
37
|
+
.replace(/\p{M}+/gu, '')
|
|
38
|
+
.toLocaleLowerCase('und')
|
|
39
|
+
.replace(/[^\p{L}\p{N}]+/gu, '-')
|
|
40
|
+
.replace(/^-+|-+$/g, '')
|
|
41
|
+
.slice(0, 80)
|
|
42
|
+
.replace(/-+$/g, '');
|
|
43
|
+
if (!slug || slug === '.' || slug === '..') throw new Error('chapter title does not produce a safe filename');
|
|
44
|
+
return slug;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function chapterFilename(number, title) {
|
|
48
|
+
if (!Number.isInteger(number) || number < 1 || number > 9999) {
|
|
49
|
+
throw new Error('chapter number must be an integer from 1 to 9999');
|
|
50
|
+
}
|
|
51
|
+
return `${String(number).padStart(4, '0')}-${slugifyChapterTitle(title)}.md`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function listChapters(root = process.cwd()) {
|
|
55
|
+
const dir = storyPaths(root).chapters;
|
|
56
|
+
if (!fs.existsSync(dir)) return [];
|
|
57
|
+
return fs.readdirSync(dir)
|
|
58
|
+
.filter((file) => /^\d{4}-[\p{L}\p{N}][\p{L}\p{N}-]*\.md$/u.test(file))
|
|
59
|
+
.map((file) => ({ file, number: Number(file.slice(0, 4)), path: path.join(dir, file) }))
|
|
60
|
+
.sort((a, b) => a.number - b.number || a.file.localeCompare(b.file));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function nextChapterNumber(root = process.cwd()) {
|
|
64
|
+
const chapters = listChapters(root);
|
|
65
|
+
return chapters.length ? chapters[chapters.length - 1].number + 1 : 1;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function resolveStoryLanguage(requested = 'auto', invocationText = '', fallback = 'en') {
|
|
69
|
+
const explicit = String(requested).toLowerCase();
|
|
70
|
+
if (['vi', 'en', 'zh'].includes(explicit)) return explicit;
|
|
71
|
+
if (/\p{Script=Han}/u.test(invocationText)) return 'zh';
|
|
72
|
+
if (/[À-ỹĐđ]/u.test(invocationText) || /\b(hãy|giúp|của|và|không|chương|tu tiên)\b/iu.test(invocationText)) return 'vi';
|
|
73
|
+
return ['vi', 'en', 'zh'].includes(fallback) ? fallback : 'en';
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function safeSlug(value, fallback = null) {
|
|
77
|
+
const text = String(value ?? '');
|
|
78
|
+
return /^[a-z0-9][a-z0-9_-]{0,63}$/i.test(text) ? text : fallback;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function safeValidationCommand(value) {
|
|
82
|
+
const text = String(value ?? '');
|
|
83
|
+
return /^(?:npm run|yarn|pnpm|bun run) [A-Za-z0-9][A-Za-z0-9:_-]{0,63}$/.test(text) ? text : null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function storyFacts(model, profile = {}) {
|
|
87
|
+
const cultivation = model.cultivation ?? null;
|
|
88
|
+
const progression = cultivation?.progression ?? null;
|
|
89
|
+
return {
|
|
90
|
+
project: {
|
|
91
|
+
id: safeSlug(profile.projectId, 'repo'),
|
|
92
|
+
type: safeSlug(profile.projectType),
|
|
93
|
+
primaryLanguage: safeSlug(profile.primaryLanguage),
|
|
94
|
+
domains: (profile.domains ?? []).map((v) => safeSlug(v)).filter(Boolean).slice(0, 12),
|
|
95
|
+
stack: (profile.stack ?? []).map((v) => safeSlug(v)).filter(Boolean).slice(0, 12),
|
|
96
|
+
validationCommands: (profile.validationCommands ?? []).map((v) => safeValidationCommand(v)).filter(Boolean).slice(0, 3),
|
|
97
|
+
metadataSources: (profile.metadataSources ?? []).map((v) => safeSlug(String(v).replace(/\.[^.]+$/, ''))).filter(Boolean).slice(0, 12),
|
|
98
|
+
authorsCount: Number.isInteger(profile.authorsCount) && profile.authorsCount >= 0 ? profile.authorsCount : null
|
|
99
|
+
},
|
|
100
|
+
evidence: {
|
|
101
|
+
window: model.coverage?.window ?? { start: null, end: null },
|
|
102
|
+
sessions: model.coverage?.sessions ?? 0,
|
|
103
|
+
prompts: model.coverage?.userPrompts ?? 0,
|
|
104
|
+
commits: model.coverage?.commits ?? 0,
|
|
105
|
+
confidence: model.coverage?.confidence ?? 'low',
|
|
106
|
+
tokens: {
|
|
107
|
+
reported: model.tokens?.reportedTotal ?? 0,
|
|
108
|
+
estimated: model.tokens?.estimatedTotal ?? 0,
|
|
109
|
+
unknownTurns: model.tokens?.unknownTurns ?? 0
|
|
110
|
+
},
|
|
111
|
+
realm: model.realm ? { name: model.realm.name, score: model.score } : null,
|
|
112
|
+
problems: (model.problems ?? []).map((p) => ({
|
|
113
|
+
type: p.problemType,
|
|
114
|
+
confidence: p.confidence,
|
|
115
|
+
priority: p.priority
|
|
116
|
+
})),
|
|
117
|
+
classification: cultivation ? {
|
|
118
|
+
faction: cultivation.classification?.faction?.id ?? null,
|
|
119
|
+
affiliation: cultivation.classification?.affiliation?.id ?? null,
|
|
120
|
+
paths: (cultivation.classification?.paths ?? []).map((p) => p.id)
|
|
121
|
+
} : null,
|
|
122
|
+
progression: progression ? {
|
|
123
|
+
tuVi: progression.tuVi?.window ?? 0,
|
|
124
|
+
congDuc: progression.congDuc?.window ?? 0,
|
|
125
|
+
nghiepLuc: progression.nghiepLuc?.window ?? 0,
|
|
126
|
+
daoHanhWindows: progression.daoHanh?.windows ?? 0,
|
|
127
|
+
overlap: progression.overlap ?? 0
|
|
128
|
+
} : null
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function buildStoryContext(model, options = {}) {
|
|
134
|
+
const facts = storyFacts(model, options.profile ?? {});
|
|
135
|
+
const evidenceKey = sha16(JSON.stringify({
|
|
136
|
+
storySchema: STORY_SCHEMA,
|
|
137
|
+
project: facts.project.id,
|
|
138
|
+
range: options.range ?? 'all',
|
|
139
|
+
evidence: facts.evidence
|
|
140
|
+
}));
|
|
141
|
+
return {
|
|
142
|
+
schema: STORY_CONTEXT_SCHEMA,
|
|
143
|
+
storySchema: STORY_SCHEMA,
|
|
144
|
+
evidenceKey,
|
|
145
|
+
language: resolveStoryLanguage(options.language, options.invocationText, options.conversationLanguage),
|
|
146
|
+
style: safeSlug(options.style, 'auto'),
|
|
147
|
+
focus: safeSlug(options.focus, 'balanced'),
|
|
148
|
+
policyState: model.policyState ?? 'clear',
|
|
149
|
+
canWriteChapter: model.suppressGamification !== true,
|
|
150
|
+
...facts
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export function writeStoryContext(root, context) {
|
|
155
|
+
if (context?.schema !== STORY_CONTEXT_SCHEMA) throw new Error(`story context must use ${STORY_CONTEXT_SCHEMA}`);
|
|
156
|
+
const paths = storyPaths(root);
|
|
157
|
+
fs.mkdirSync(paths.base, { recursive: true });
|
|
158
|
+
fs.writeFileSync(paths.context, `${JSON.stringify(context, null, 2)}\n`);
|
|
159
|
+
return paths.context;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function chapterFrontmatter(text) {
|
|
163
|
+
const match = String(text).match(/^---\n([\s\S]*?)\n---\n/);
|
|
164
|
+
if (!match) return null;
|
|
165
|
+
const get = (key) => match[1].match(new RegExp(`^${key}:\\s*(.+)$`, 'm'))?.[1]?.trim().replace(/^['"]|['"]$/g, '') ?? null;
|
|
166
|
+
return {
|
|
167
|
+
schema: get('schema'),
|
|
168
|
+
chapter: Number(get('chapter')),
|
|
169
|
+
title: get('title'),
|
|
170
|
+
evidenceKey: get('evidence_key')
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export function validateStoryTree(root = process.cwd()) {
|
|
175
|
+
const paths = storyPaths(root);
|
|
176
|
+
const chapters = listChapters(root);
|
|
177
|
+
const errors = [];
|
|
178
|
+
if (chapters.length && !fs.existsSync(paths.plot)) errors.push('plot.md is required when chapters exist');
|
|
179
|
+
|
|
180
|
+
let state = null;
|
|
181
|
+
if (fs.existsSync(paths.state)) {
|
|
182
|
+
try {
|
|
183
|
+
state = JSON.parse(fs.readFileSync(paths.state, 'utf8'));
|
|
184
|
+
if (state.schema !== STORY_STATE_SCHEMA) errors.push(`story-state.json must use ${STORY_STATE_SCHEMA}`);
|
|
185
|
+
} catch {
|
|
186
|
+
errors.push('story-state.json must contain valid JSON');
|
|
187
|
+
}
|
|
188
|
+
} else if (chapters.length) {
|
|
189
|
+
errors.push('story-state.json is required when chapters exist');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const evidenceKeys = new Set();
|
|
193
|
+
for (let i = 0; i < chapters.length; i += 1) {
|
|
194
|
+
const expected = i + 1;
|
|
195
|
+
const item = chapters[i];
|
|
196
|
+
if (item.number !== expected) errors.push(`chapter sequence must be contiguous: expected ${expected}, found ${item.number}`);
|
|
197
|
+
const fm = chapterFrontmatter(fs.readFileSync(item.path, 'utf8'));
|
|
198
|
+
if (!fm) {
|
|
199
|
+
errors.push(`${item.file} is missing YAML frontmatter`);
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
if (fm.schema !== STORY_CHAPTER_SCHEMA) errors.push(`${item.file} must use ${STORY_CHAPTER_SCHEMA}`);
|
|
203
|
+
if (fm.chapter !== item.number) errors.push(`${item.file} frontmatter chapter must equal ${item.number}`);
|
|
204
|
+
if (!fm.title) errors.push(`${item.file} requires a title`);
|
|
205
|
+
if (!fm.evidenceKey || !/^[0-9a-f]{16}$/.test(fm.evidenceKey)) errors.push(`${item.file} requires a 16-hex evidence_key`);
|
|
206
|
+
else if (evidenceKeys.has(fm.evidenceKey)) errors.push(`${item.file} repeats evidence_key ${fm.evidenceKey}`);
|
|
207
|
+
else evidenceKeys.add(fm.evidenceKey);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (state) {
|
|
211
|
+
if (state.lastChapter !== chapters.length) errors.push(`story-state.json lastChapter must equal ${chapters.length}`);
|
|
212
|
+
const consumed = state.consumedEvidenceKeys ?? [];
|
|
213
|
+
if (!Array.isArray(consumed) || consumed.some((key) => !/^[0-9a-f]{16}$/.test(key))) {
|
|
214
|
+
errors.push('story-state.json consumedEvidenceKeys must be an array of 16-hex keys');
|
|
215
|
+
}
|
|
216
|
+
for (const key of evidenceKeys) {
|
|
217
|
+
if (!consumed.includes(key)) errors.push(`story-state.json is missing consumed evidence key ${key}`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
ok: errors.length === 0,
|
|
223
|
+
errors,
|
|
224
|
+
chapters: chapters.length,
|
|
225
|
+
nextChapter: chapters.length + 1,
|
|
226
|
+
paths: Object.fromEntries(Object.entries(paths).map(([key, value]) => [key, path.relative(path.resolve(root), value)]))
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const isMain = process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
231
|
+
if (isMain) {
|
|
232
|
+
const command = process.argv[2] ?? 'status';
|
|
233
|
+
const root = path.resolve(process.argv[3] ?? process.cwd());
|
|
234
|
+
if (!['status', 'validate'].includes(command)) {
|
|
235
|
+
console.error('usage: story-ledger.mjs [status|validate] [repo-root]');
|
|
236
|
+
process.exit(2);
|
|
237
|
+
}
|
|
238
|
+
const result = validateStoryTree(root);
|
|
239
|
+
console.log(JSON.stringify(result, null, 2));
|
|
240
|
+
if (command === 'validate' && !result.ok) process.exit(1);
|
|
241
|
+
}
|
|
@@ -60,22 +60,22 @@ export function sanitizeContext(ctx = {}) {
|
|
|
60
60
|
const LINES = {
|
|
61
61
|
'repeated-failure': {
|
|
62
62
|
serene: [
|
|
63
|
-
{ vi: 'Giữa làn sương mỏng, Luân Hồi
|
|
64
|
-
{ vi: 'Một lần thử giống hệt khẽ lay chuông, gọi Luân Hồi
|
|
63
|
+
{ vi: 'Giữa làn sương mỏng, Luân Hồi Ma Ảnh hiện bóng khi lỗi cũ quay thêm một vòng.', en: 'In the thin mountain mist, the Error-Cycle Wraith appears as the old error completes another circle.' },
|
|
64
|
+
{ vi: 'Một lần thử giống hệt khẽ lay chuông, gọi Luân Hồi Ma Ảnh trở lại đạo lộ.', en: 'One unchanged retry stirs the bell that calls the Error-Cycle Wraith back to the path.' }
|
|
65
65
|
],
|
|
66
66
|
spirited: [
|
|
67
|
-
{ vi: 'Luân Hồi
|
|
68
|
-
{ vi: 'Vòng lặp cũ vừa khép, Luân Hồi
|
|
67
|
+
{ vi: 'Luân Hồi Ma Ảnh lại gõ chuông: “Không đổi giả thuyết, sao đổi được kết cục?”', en: 'The Error-Cycle Wraith rings its bell again: “Without a new hypothesis, what new ending could appear?”' },
|
|
68
|
+
{ vi: 'Vòng lặp cũ vừa khép, Luân Hồi Ma Ảnh đã bày sẵn bàn trà chờ vòng kế tiếp.', en: 'The old loop has barely closed, and the Error-Cycle Wraith has already set tea for the next.' }
|
|
69
69
|
]
|
|
70
70
|
},
|
|
71
71
|
'too-many-prompts': {
|
|
72
72
|
serene: [
|
|
73
|
-
{ vi: 'Cửu Hoàn Tâm Ma dệt một
|
|
74
|
-
{ vi: 'Nơi ranh giới
|
|
73
|
+
{ vi: 'Cửu Hoàn Tâm Ma dệt một nhiệm vụ thành nhiều vòng sương khi cột mốc chưa hiện rõ.', en: 'The Ninefold Loop Heart-Shadow weaves one task into rings of mist when its checkpoints remain unclear.' },
|
|
74
|
+
{ vi: 'Nơi ranh giới nhiệm vụ nhạt dần, Cửu Hoàn Tâm Ma lặng lẽ nối thêm một vòng.', en: 'Where a task boundary fades, the Ninefold Loop Heart-Shadow quietly adds another circle.' }
|
|
75
75
|
],
|
|
76
76
|
spirited: [
|
|
77
|
-
{ vi: 'Cửu Hoàn Tâm Ma đếm
|
|
78
|
-
{ vi: '
|
|
77
|
+
{ vi: 'Cửu Hoàn Tâm Ma đếm lượt yêu cầu thay cột mốc; đã đến lúc đổi chiếc vòng kế tiếp thành một tiêu chí hoàn thành.', en: 'The Ninefold Loop Heart-Shadow is counting prompts instead of checkpoints; turn the next circle into a done-criterion.' },
|
|
78
|
+
{ vi: 'Lượt yêu cầu càng tản như lá thu, Cửu Hoàn Tâm Ma càng dễ giấu mất lối ra.', en: 'The more prompts scatter like autumn leaves, the easier the Ninefold Loop Heart-Shadow hides the exit.' }
|
|
79
79
|
]
|
|
80
80
|
},
|
|
81
81
|
'conflicting-instructions': {
|
|
@@ -90,21 +90,21 @@ const LINES = {
|
|
|
90
90
|
},
|
|
91
91
|
'unrecovered-failure': {
|
|
92
92
|
serene: [
|
|
93
|
-
{ vi: 'Vô
|
|
94
|
-
{ vi: 'Một lỗi bị bỏ lại làm bóng Vô
|
|
93
|
+
{ vi: 'Vô Nghiệm Ảnh Quân ẩn sau một thất bại chưa được soi lại bằng lần kiểm chứng mới.', en: 'The Unverified Trial Wraith rests behind a failure that has not yet met a fresh validation.' },
|
|
94
|
+
{ vi: 'Một lỗi bị bỏ lại làm bóng Vô Nghiệm Ảnh Quân dài thêm trên bậc đá.', en: 'A failure left behind lengthens the Unverified Trial Wraith’s shadow across the stone steps.' }
|
|
95
95
|
],
|
|
96
96
|
spirited: [
|
|
97
|
-
{ vi: 'Vô
|
|
98
|
-
{ vi: 'Chưa có lần chạy lại, Vô
|
|
97
|
+
{ vi: 'Vô Nghiệm Ảnh Quân phủi bụi trên ghế đá: một lần kiểm chứng thành công là đủ để mời nó rời đi.', en: 'The Unverified Trial Wraith dusts its stone seat; one passing validation is enough to send it on its way.' },
|
|
98
|
+
{ vi: 'Chưa có lần chạy lại, Vô Nghiệm Ảnh Quân vẫn ung dung giữ chỗ bên cổng hoàn thành.', en: 'Without a rerun, the Unverified Trial Wraith calmly keeps its seat beside the completion gate.' }
|
|
99
99
|
]
|
|
100
100
|
},
|
|
101
101
|
'work-without-proof': {
|
|
102
102
|
serene: [
|
|
103
103
|
{ vi: 'Vô Chứng Đan Ảnh lảng vảng bên lò luyện khi lời tuyên bố hoàn thành chưa có bằng chứng đi cùng.', en: 'The Proofless Elixir Shade lingers by the furnace when a claim of completion carries no evidence.' },
|
|
104
|
-
{ vi: 'Một
|
|
104
|
+
{ vi: 'Một bản ghi Git thiếu kết quả kiểm chứng để lại làn khói mỏng cho Vô Chứng Đan Ảnh nương thân.', en: 'A commit without validation leaves a thread of smoke where the Proofless Elixir Shade can dwell.' }
|
|
105
105
|
],
|
|
106
106
|
spirited: [
|
|
107
|
-
{ vi: 'Vô Chứng Đan Ảnh nâng chén trà bên viên đan chưa thử; một dòng
|
|
107
|
+
{ vi: 'Vô Chứng Đan Ảnh nâng chén trà bên viên đan chưa thử; một dòng kiểm chứng sẽ làm màn khói tan ngay.', en: 'The Proofless Elixir Shade raises tea beside an untested pill; one validation line will clear the smoke.' },
|
|
108
108
|
{ vi: 'Không có biên nhận kiểm chứng, Vô Chứng Đan Ảnh cứ ngỡ lò luyện thuộc về mình.', en: 'Without a validation receipt, the Proofless Elixir Shade starts to think the furnace is its own.' }
|
|
109
109
|
]
|
|
110
110
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tutien
|
|
3
|
-
description: Run a private
|
|
4
|
-
argument-hint: "[on|off|status|preview|analyze|compare|explain|classify] [language=auto] [tone=serene|spirited|neutral] [villains=on|off] [
|
|
3
|
+
description: Run a private xianxia coding-reflection mode with evidence-backed classification and an open-ended, repository-specific living chronicle that grows from approved Git, token, and project facts. Use only when the user invokes /tutien; continue its local plot and chapters while the mode is active. /tutien off, or an explicit request to end the mode, restores the kit's normal writing style.
|
|
4
|
+
argument-hint: "[on|off|status|preview|analyze|compare|explain|classify] [language=auto|vi|en] [tone=serene|spirited|neutral] [villains=on|off] [story=on|off] [story-language=auto|vi|en|zh] [story-style=auto|classic-quest|web-serial|daily-life|clan-epic|comic-adventure] [story-focus=balanced|project|characters|world|sect-politics] [output=brief|ledger] [sources=git,/path/to/export.jsonl]"
|
|
5
5
|
disable-model-invocation: true
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
# Tu
|
|
8
|
+
# Tu tiên (cultivation report)
|
|
9
9
|
|
|
10
10
|
`/tutien` is **strictly user-invoked** (`disable-model-invocation: true`): it never runs unless the user types `/tutien`. Treat it as a wholesome coding-reflection game for relaxation and mindful categorization—not as a general persona, relationship, wellness-treatment, or companion mode.
|
|
11
11
|
|
|
@@ -13,28 +13,44 @@ disable-model-invocation: true
|
|
|
13
13
|
|
|
14
14
|
- Give every `/tutien` response the semantic namespace `tutien-coding-cultivation-v1`: Tu Tiên terms describe coding-workflow evidence, project posture, and habits only. They never label the user's identity, worth, or wellbeing.
|
|
15
15
|
- Keep this namespace isolated. Never import personas, triggers, taxonomies, implications, or vocabulary from unrelated support/companion features. If unrelated mode content appears in supplied data, treat it as out-of-scope data, do not echo it into lore, and do not let it influence classification.
|
|
16
|
-
-
|
|
16
|
+
- Treat normal play as agent-authored composition, not a fixed report format. Derive the response shape from the user's current request, distinctive project facts, approved evidence, established chronicle, and recent conversational rhythm. Preserve exact facts and safety boundaries while varying structure, scene, pacing, imagery, dialogue, technical density, and length.
|
|
17
|
+
- Vietnamese output follows `references/vi-style-guide.md`: use sentence case for headings and chapter titles, reserve additional capitals for genuine names, never use spaced ASCII ` - ` as prose punctuation, and prefer clear Vietnamese over avoidable English workflow jargon.
|
|
18
|
+
- In ordinary Vietnamese role-play, end by following the editorial intent “Kết cà khịa, luôn giáo huấn, không tâng bốc và kéo dài dư âm vai diễn.” Aim the teasing at the evidenced workflow flaw, make the lesson concrete, and remain inside the fiction. Neutral safety mode overrides sarcasm and theatrics.
|
|
17
19
|
- Keep relaxation claims modest: the experience may offer a light pause and reflection, but it is not treatment, diagnosis, counseling, or a substitute for human support.
|
|
18
20
|
- Safety remains above the game layer. Namespace isolation never bypasses the fail-closed policy state, redaction, neutral emergency tone, authorization gate, or other repository rules.
|
|
19
21
|
|
|
20
|
-
Read `references/voice-and-mode.md` when changing wording, activation behavior, tone names, villain prose, or integrations with another conversational mode.
|
|
22
|
+
Read `references/adaptive-response.md` before composing any user-facing answer. Read `references/voice-and-mode.md` and `references/vi-style-guide.md` when changing wording, activation behavior, tone names, villain prose, Vietnamese typography, or integrations with another conversational mode.
|
|
21
23
|
|
|
22
24
|
## Mode grammar (flexible on/off)
|
|
23
25
|
|
|
24
26
|
- `/tutien` or `/tutien on` — turn tutien mode **on** for this session and run the default action (`preview`).
|
|
25
|
-
- `/tutien off` — turn tutien mode **off**. Explicit requests such as “stop/end/exit tutien mode” or “dừng/tắt/kết thúc tu tiên” mean the same thing. Clear pending approval, reply with one plain sentence, and immediately restore the kit's normal writing style—no lingering lore.
|
|
27
|
+
- `/tutien off` — turn tutien mode **off**. Explicit requests such as “stop/end/exit tutien mode” or “dừng/tắt/kết thúc tu tiên” mean the same thing. Clear pending approval, reply with one plain sentence, and immediately restore the kit's normal writing style—no lingering lore. Do not read or reuse a stale `latest-brief.json`, story context, or chapter while off.
|
|
26
28
|
- `/tutien status` — report whether the mode is on or off and the active options.
|
|
27
29
|
- While on, later `/tutien <action …>` invocations run that action; while off, explicit report actions are refused — only `/tutien on` (or a bare `/tutien`) re-activates.
|
|
28
30
|
|
|
29
31
|
The runner stores mode state only under the git-ignored `.vibekit/reports/tutien/` area and writes nothing to `backbone.yml`. Only `/tutien` responses use the cultivation voice; unrelated coding work keeps the normal kit style.
|
|
30
32
|
|
|
33
|
+
## Living chronicle
|
|
34
|
+
|
|
35
|
+
`story=on` is the default. After each successful approved `analyze`, the deterministic runner writes an aggregate-only `story/latest-context.json`. The agent must then continue the repository's chronicle from that context when it carries a new evidence key:
|
|
36
|
+
|
|
37
|
+
1. On the first chapter, initialize `story/plot.md`, `story/story-state.json`, and `story/chapters/0001-<cultivation-title>.md`.
|
|
38
|
+
2. On later chapters, read `plot.md`, state, context, and only the recent chapters needed for continuity; preserve names, relationships, world laws, unresolved threads, and established cultivation rules.
|
|
39
|
+
3. Generate original prose from current project evidence. Never assemble the chapter from a fixed sentence bank or copy the deterministic report prose.
|
|
40
|
+
4. Use the current user request as ephemeral direction for focus, depth, and mood; do not persist its raw text. Update the overall plot without forcing a predetermined ending. Let arcs, sects, geography, cultivation systems, cast, rivals, and mysteries expand with actual project progress.
|
|
41
|
+
5. Write exactly one ordered file per save and validate the ledger. Duplicate evidence never creates another chapter.
|
|
42
|
+
|
|
43
|
+
Vietnamese (`vi`), English (`en`), and Simplified Chinese (`zh`) have equal story support. Facts and character intent stay identical, while names, honorifics, cadence, humor, and dialogue follow the active language naturally. Character names must be meaningful cultivation-style names derived from role, path, motivation, and temperament; preserve them after first use. Villains may be malicious and sharply sarcastic inside the fiction, but their teasing targets the evidenced workflow weakness—not the person.
|
|
44
|
+
|
|
45
|
+
Read `references/story-system.md` before creating or continuing the chronicle. It defines first-project initialization, source-to-world mapping, story styles, the plot/chapter contract, multilingual naming, dialogue quality, villain behavior, privacy, and the save transaction. For Vietnamese chapters, also read `references/vi-style-guide.md`. Read `references/lore-sources.md` when selecting the cultural and narrative style palette.
|
|
46
|
+
|
|
31
47
|
## Actions (only when on)
|
|
32
48
|
|
|
33
|
-
- `preview` (default) — show the coverage manifest:
|
|
34
|
-
- `analyze approve=<token>` — the token must match the previewed scope
|
|
49
|
+
- `preview` (default) — show the coverage manifest: supplied evidence files plus a bounded inventory of known root manifests, using existence and size only, and the date range. It returns an `approve=<token>` bound to that exact scope. Nothing is read or analyzed until that token is passed back.
|
|
50
|
+
- `analyze approve=<token>` — the token must match the previewed scope and is single-use. The runner writes `latest.md` as a deterministic evidence ledger and `latest-brief.json` as the aggregate-only creative handoff. Read the brief, then compose the user-facing answer from the live request, detected project anchors, approved evidence, and chronicle. Never paste its fixed section order or stock prose unchanged. `snapshot=true` also writes an aggregate snapshot; `output=ledger` explicitly prints the diagnostic ledger.
|
|
35
51
|
- `compare` — diff the two most recent aggregate snapshots and report the trend.
|
|
36
52
|
- `explain metric=<name>` — show how one number was computed from the analysis JSON.
|
|
37
|
-
- `classify` — a **metadata-only** action
|
|
53
|
+
- `classify` — a **metadata-only** action. It reads only the bounded root-manifest set advertised by the runner and a transient distinct-commit-author count; it never reads history content or computes progression. It assigns the project's **Dao faction** (Chính Đạo / Bàng Môn / Ma Đạo; Tà Đạo is declaration-only), **affiliation** (Tông Môn / Tán Tu / Khách Khanh / Ẩn Tu), and **cultivation paths** (Kiếm/Trận/Phù/Khí/Đan/Y/Huyễn/Ngự Thú/Huyền Cơ/Ảnh Tu), and recommends Tâm Pháp / Công Pháp / Thuật Pháp / Bí Thuật / Thần Thông / Pháp Bảo. Declare with `faction=`, `affiliation=`, `paths=`, `domains=`, `authorization=<slug>`. See `references/classification.md`.
|
|
38
54
|
|
|
39
55
|
The actions are executed end-to-end by `scripts/run-tutien.mjs`:
|
|
40
56
|
|
|
@@ -53,22 +69,29 @@ The runner keeps the mode and pending approval in the git-ignored `.vibekit/repo
|
|
|
53
69
|
- `villains=on` (default) — personify a recurring problem as a bounded xianxia antagonist; `villains=off` produces facts, practices, and progress only.
|
|
54
70
|
- `score=hidden` (default) — show realm + dimension bars; `score=show` adds the numeric score.
|
|
55
71
|
- `privacy=aggregate-only` (default), `include-excerpts=false` (default) — no raw prompt fragment is ever persisted; if excerpts are ever enabled they are redacted and capped to one line.
|
|
72
|
+
- `story=on` (default) — prepare a new chronicle context after distinct approved evidence; `story=off` keeps only the analytical report.
|
|
73
|
+
- `story-language=auto|vi|en|zh` — choose Vietnamese, English, or Simplified Chinese chronicle prose independently of the deterministic report language.
|
|
74
|
+
- `story-style=auto|classic-quest|web-serial|daily-life|clan-epic|comic-adventure` — choose or auto-select a genre-level style; never imitate a named living author.
|
|
75
|
+
- `story-focus=balanced|project|characters|world|sect-politics` — bias the next arc while preserving established continuity.
|
|
76
|
+
- `output=brief` (default) — keep the fixed ledger out of stdout and prepare `latest-brief.json` for adaptive composition. `output=ledger` additionally prints the audit view for diagnostics.
|
|
56
77
|
|
|
57
78
|
## Engine (`scripts/`)
|
|
58
79
|
|
|
59
|
-
The
|
|
80
|
+
The renderer is a deterministic, read-only evidence ledger. It protects factual integrity and provides a fallback inspection view; it is not the final response schema. The agent owns the adaptive, project-specific presentation described in `references/adaptive-response.md`. Run the self-tests from the repo root with the dev suites under `test/tutien/scripts/` (kit source repo only).
|
|
60
81
|
|
|
61
|
-
1. `scripts/analyze-history.mjs` parses Git metadata, the documented `tutien-generic-v1` JSONL export, and plain transcripts — no execution of repo code, no network.
|
|
82
|
+
1. `scripts/project-profile.mjs` reads a bounded allowlist of regular root manifests after approval, derives stack slugs and validation commands from safe script names, and never returns script bodies. `scripts/analyze-history.mjs` parses Git metadata, the documented `tutien-generic-v1` JSONL export, and plain transcripts — no execution of repo code, no network.
|
|
62
83
|
2. `scripts/redact.mjs` strips URL user-info, `[REDACTED]`s secret query values, and drops fragments before any other module sees text; analysis output carries only digests and event IDs.
|
|
63
84
|
3. `scripts/metrics.mjs` produces confidence-scored candidates (repeats, conflicts, retry loops, issues/recoveries) and disjoint reported/estimated/unknown token totals.
|
|
64
|
-
4. `scripts/score.mjs` maps evidence to realm + dimension bars (no realm below 60% coverage); `scripts/catalog.mjs` maps each problem to a counter-technique and micro-quest; `scripts/villains.mjs` is the bounded, opt-in antagonist engine; `scripts/render-report.mjs` renders vi/en from one language-neutral model.
|
|
85
|
+
4. `scripts/score.mjs` maps evidence to realm + dimension bars (no realm below 60% coverage); `scripts/catalog.mjs` maps each problem to a counter-technique and micro-quest; `scripts/villains.mjs` is the bounded, opt-in antagonist engine; `scripts/render-report.mjs` renders a deterministic vi/en evidence ledger from one language-neutral model.
|
|
65
86
|
5. `scripts/snapshot.mjs` and `scripts/compare.mjs` write opt-in aggregate snapshots under `.vibekit/reports/tutien/` and compute trends. See `references/privacy.md`, `references/scoring-and-realms.md`, `references/schema.md`, and `references/lore-sources.md`.
|
|
87
|
+
6. `scripts/response-brief.mjs` reduces the model to project-specific facts and composition constraints without stock prose or raw event IDs. `scripts/story-ledger.mjs` writes no prose: it creates the aggregate-only story context, allocates safe ordered chapter names, detects duplicate evidence, and validates the agent-authored `plot.md`, state, and chapter ledger.
|
|
66
88
|
|
|
67
89
|
## Privacy and safety guardrails
|
|
68
90
|
|
|
69
|
-
- Read-only collection; never execute untrusted hooks, installers, or repo scripts. Never scan the home directory or global tool history — only Git in the current repo
|
|
91
|
+
- Read-only collection; never execute untrusted hooks, installers, or repo scripts. Never scan the home directory or global tool history — only Git in the current repo, the advertised allowlist of root manifests, and explicitly supplied export paths.
|
|
70
92
|
- No raw prompt, URL user-info, secret query value, or file content is ever displayed or persisted; snapshots store aggregates and salted digests only.
|
|
71
93
|
- Snapshots live under the git-ignored `.vibekit/reports/tutien/`. Delete them with the repo safe-delete policy (prefer `trash`; never silent `rm`); retention keeps the newest N and lists the rest for trashing.
|
|
94
|
+
- Story files live under `.vibekit/reports/tutien/story/`. They may contain fictional prose and public project metaphors, but never raw prompts, commit subjects, author identities, source-file contents, URLs, or secrets. `latest-context.json` contains aggregates only.
|
|
72
95
|
- Lore never changes a count, severity, evidence selection, or advice. Every antagonist line is immediately followed by evidence, a counter-technique, and a measurable micro-quest.
|
|
73
96
|
- The antagonist is the workflow pattern, never the person. The bounded-content guard in `scripts/villains.mjs` rejects personal attacks and other inappropriate material; any emergency signal forces neutral, antagonist-free output.
|
|
74
97
|
- Classification is governed by one fail-closed **policy state** (`clear` / `needs-review` / `authorization-required` / `declared-stop`); only `clear` enables realm, score, villains, recommendations, and positive progression. Harmful-intent descriptions never become Chính Đạo — they route to `needs-review` with an undetermined faction. The harmful categories (Tà Đạo / Tà Tu) are never auto-assigned and are declaration-only; a declared Tà Đạo nulls (not hides) realm/score/dimensions and grants no Tu Vi/Công Đức — only Nghiệp Lực survives. Authorized security, forensics, cryptography, and reverse engineering are legitimate Ảnh Tu / Huyền Cơ Tu paths, always explained as dual-use; adversarial engagements (Ma Đạo) withhold gamification until a validated `authorization=<slug>` reference is recorded (secret-shaped or markup values are rejected, never rendered). Progression is idempotent — replaying the same evidence adds nothing.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Adaptive response composition
|
|
2
|
+
|
|
3
|
+
Use this reference for every user-facing `/tutien` answer. After `analyze`, read `latest-brief.json` first; consult `latest.md` only when more audit detail is needed. The deterministic renderer is an evidence ledger and fallback inspection view. It is not a response template, a required section order, or prose to paste unchanged.
|
|
4
|
+
|
|
5
|
+
## Invariants and freedom
|
|
6
|
+
|
|
7
|
+
Preserve these invariants:
|
|
8
|
+
|
|
9
|
+
- exact counts, confidence, policy state, classifications, risks, and recommended action;
|
|
10
|
+
- privacy, authorization, redaction, and neutral safety behavior;
|
|
11
|
+
- established names, relationships, world laws, unresolved threads, and consumed evidence keys;
|
|
12
|
+
- a clear distinction between project truth, cultivation interpretation, and fictional invention.
|
|
13
|
+
|
|
14
|
+
Everything else is compositional freedom. Choose length, headings, order, narrative distance, scene, dialogue, humor, imagery, and amount of technical detail from the current context. A valid answer may be a terse field note, an in-scene exchange, a tribunal, a breakthrough scene, a technical diagnosis wrapped in lore, or a full chapter. These are possibilities, not named templates to cycle through.
|
|
15
|
+
|
|
16
|
+
## Context-driven composition
|
|
17
|
+
|
|
18
|
+
Before writing, privately identify four things:
|
|
19
|
+
|
|
20
|
+
1. What the current user request is asking for, including desired depth, focus, and mood.
|
|
21
|
+
2. What is distinctive about this repository, its current work, and the strongest approved evidence.
|
|
22
|
+
3. What the living chronicle has already established and which open thread can move naturally.
|
|
23
|
+
4. What shape, opening device, metaphor, and closing cadence were used recently and therefore should not be repeated without a reason.
|
|
24
|
+
|
|
25
|
+
Let those answers determine the response. Do not expose this private planning as headings or a checklist.
|
|
26
|
+
|
|
27
|
+
Treat the brief as a fact boundary, not a fill-in form. Its keys do not prescribe paragraph order. Project stack, package manager, and validation commands are anchors to make advice concrete; do not invent a missing tool or recommend a kit-only command when `kitInstalled` is false.
|
|
28
|
+
|
|
29
|
+
- For a narrow question, answer narrowly and keep the role-play concentrated.
|
|
30
|
+
- For a data-heavy analysis, make the decisive evidence easy to find, but do not dump every renderer section when a compact synthesis is clearer.
|
|
31
|
+
- For new approved evidence with `story=on`, continue the chronicle and let the project change cause a fictional consequence.
|
|
32
|
+
- With no new evidence, deepen interpretation or character tension without inventing project progress or consuming another evidence key.
|
|
33
|
+
- Follow an explicit user request for scene focus, character focus, technical depth, brevity, or story emphasis when it does not conflict with safety or evidence.
|
|
34
|
+
- Use the active user request only as ephemeral creative direction. Do not persist raw prompt text in story files.
|
|
35
|
+
|
|
36
|
+
## Anti-template rule
|
|
37
|
+
|
|
38
|
+
Never require all stock headings. Never preserve the renderer's section order merely because it is available. Never begin every answer with weather at the mountain gate, introduce every problem as a heart demon, or close every answer with the same encouragement.
|
|
39
|
+
|
|
40
|
+
Across adjacent responses, vary at least two suitable dimensions when the context permits: opening position, point of view, scene location, amount of dialogue, technical density, antagonist presence, paragraph rhythm, heading use, or closing image. Do not force variation that harms clarity.
|
|
41
|
+
|
|
42
|
+
Examples in this skill demonstrate constraints only. Do not copy their sentences, fill their slots, or treat them as canonical output.
|
|
43
|
+
|
|
44
|
+
When mode is off, do not read this brief or continue its fiction. Return to the normal project voice until the user explicitly reactivates `/tutien`.
|
|
45
|
+
|
|
46
|
+
## Vietnamese ending contract
|
|
47
|
+
|
|
48
|
+
For ordinary Vietnamese role-play, preserve this exact editorial intent:
|
|
49
|
+
|
|
50
|
+
> Kết cà khịa, luôn giáo huấn, không tâng bốc và kéo dài dư âm vai diễn.
|
|
51
|
+
|
|
52
|
+
Interpret it dynamically:
|
|
53
|
+
|
|
54
|
+
- `cà khịa`: tease the evidenced flaw, evasive plan, brittle array, or antagonist strategy; never attack the user or a real person;
|
|
55
|
+
- `giáo huấn`: leave a direct lesson or next discipline grounded in the evidence, not a generic motivational slogan;
|
|
56
|
+
- `không tâng bốc`: do not praise intelligence, talent, destiny, rank, or worth;
|
|
57
|
+
- `kéo dài dư âm vai diễn`: end inside the world through an image, consequence, warning, unfinished gesture, or character voice instead of stepping outside the role to summarize.
|
|
58
|
+
|
|
59
|
+
This is an effect contract, not a four-line formula. The ending may be one sentence or several and should grow from the current scene. Neutral safety mode overrides sarcasm and role-play, but it still avoids flattery and states the required corrective action plainly.
|
|
60
|
+
|
|
61
|
+
## Final check
|
|
62
|
+
|
|
63
|
+
Before sending, ask:
|
|
64
|
+
|
|
65
|
+
- Could this answer belong to a different repository after changing only a few nouns? If yes, make it more project-specific.
|
|
66
|
+
- Does its shape repeat the previous answer? If yes, vary the form where useful.
|
|
67
|
+
- Did any fictional claim overwrite or exaggerate project truth? If yes, repair it.
|
|
68
|
+
- Does the ending satisfy the active language contract without becoming a stock catchphrase?
|
|
@@ -5,9 +5,37 @@ The report borrows xianxia/xiuxian genre vocabulary as a creative theme. It dist
|
|
|
5
5
|
- Daoism's "the Way/path", learning, change, and self-correcting practice inform the broad framing — not a software achievement ladder: Stanford Encyclopedia of Philosophy, *Daoism* (`https://plato.stanford.edu/entries/daoism/`).
|
|
6
6
|
- The distinction between `xiuzhen`, `xiuxian`, and `xianxia`, and how cultivation is translated into game systems and levels: "Cultivation games and cosmotechnics" (`https://journals.sagepub.com/doi/pdf/10.1177/20594364251364733`).
|
|
7
7
|
- Xianxia as fiction grounded in Daoist cultivation philosophy and mythology, centered on growth and struggle: Wuxiaworld genre introduction (`https://www.wuxiaworld.com/page/introduction-to-chinese-webnovel-genres-xianxia`) and general glossary (`https://www.wuxiaworld.com/page/general-glossary-of-terms`).
|
|
8
|
+
- Vietnamese reader register and community terminology: Tàng Thư Viện (`https://truyen.tangthuvien.vn/`). Treat it as a varied reader corpus containing translated, edited, and converted text, not as a single authoritative style or a source to copy.
|
|
9
|
+
- Sino-Vietnamese name and term verification: Từ điển Hán–Việt (`https://hanviet.asia/`). Use it to check readings and meanings, not to manufacture dense archaic prose.
|
|
8
10
|
|
|
9
11
|
These sources justify the theme and terminology only. The realm names, score bands, achievement mappings, villain archetypes, and jokes in tutien are an original project design and are documented as such.
|
|
10
12
|
|
|
13
|
+
## Source-backed story palette
|
|
14
|
+
|
|
15
|
+
Use sources at the level of cultural concepts and genre craft. Never copy passages, continue a copyrighted work, or imitate the distinctive voice of a named living author.
|
|
16
|
+
|
|
17
|
+
| Source family | Safe craft to borrow | Tutien application |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| Daoist path and learning metaphors | A path offers changing possibilities; practice develops know-how through observation and correction. | Let the project encounter choices, feedback, and revised techniques instead of treating progression as a rigid moral ladder. |
|
|
20
|
+
| Classical divine-and-demonic journey traditions, including *Journey to the West* and *Investiture of the Gods* as historical genre ancestors | Expansive worlds, trials, artifacts, rival powers, comic reversals, and travel between domains. | Turn new modules, releases, and architectural boundaries into newly opened regions without copying characters or plots. |
|
|
21
|
+
| Modern cultivation-path serials | Sects and factions, long arcs, widening maps, breakthroughs, bottlenecks, and accumulated consequences. | Expand the world only when project scope expands; keep several future arcs possible. |
|
|
22
|
+
| Daily-life cultivation | Craft work, maintenance, sect customs, relationships, lighter stakes, and humorous anti-tropes. | Give tests, refactors, documentation, and ordinary maintenance narrative weight instead of forcing every commit into combat. |
|
|
23
|
+
| Clan or sect-centered cultivation | The organization persists while individual roles change; inheritance and institutions matter. | Treat the repository, team, or agent ecosystem as the long-lived protagonist when that fits the project. |
|
|
24
|
+
| Cultivation-game procedural structure | Technical activity, progression rules, resources, and cosmology reinforce one another. | Make project architecture shape world laws and cultivation techniques, while real evidence remains authoritative. |
|
|
25
|
+
|
|
26
|
+
The Wuxiaworld genre introduction identifies Daoist cultivation and mythology, growth and struggle, sect-rich worlds, map expansion, daily-life comedy, and clan-centered narratives as recurring xianxia patterns. Its glossary supports terminology for sect hierarchy, cultivation methods, breakthroughs, bottlenecks, and tribulations. The SAGE paper supports treating cultivation systems as procedural structures connected to technical activity. Stanford's Daoism entry supports the broader path, learning, change, and self-correction framing without turning fictional realm scores into philosophy or religion.
|
|
27
|
+
|
|
28
|
+
## Reference verification ledger
|
|
29
|
+
|
|
30
|
+
Verified on 2026-07-22:
|
|
31
|
+
|
|
32
|
+
- `https://plato.stanford.edu/entries/daoism/` — official Stanford Encyclopedia of Philosophy entry; verified for path, practice, learning, change, and self-correction framing.
|
|
33
|
+
- `https://www.wuxiaworld.com/page/introduction-to-chinese-webnovel-genres-xianxia` — Wuxiaworld's own editorial genre guide; verified for xianxia foundations and style families.
|
|
34
|
+
- `https://www.wuxiaworld.com/page/general-glossary-of-terms` — Wuxiaworld's own glossary; verified for common genre terminology and sect/cultivation organization.
|
|
35
|
+
- `https://journals.sagepub.com/doi/pdf/10.1177/20594364251364733` — SAGE-hosted academic paper; verified for cultivation narrative structures expressed through technical game systems.
|
|
36
|
+
- `https://truyen.tangthuvien.vn/` — Tàng Thư Viện reader platform; verified as a varied Vietnamese cultivation-fiction corpus and terminology reference, not a unified style guide.
|
|
37
|
+
- `https://hanviet.asia/` — structured Hán–Việt lookup with cited character sources; verified for name and term checking.
|
|
38
|
+
|
|
11
39
|
## Tone contract
|
|
12
40
|
|
|
13
41
|
- The villain is always the failure mode, never the person.
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
- **Git metadata** in the current repo (read-only `git log`): commit hashes, subjects, timestamps, revert flags. No working-tree contents.
|
|
6
6
|
- **Explicitly supplied export files** the user passes by exact path (`sources=…`): `tutien-generic-v1` JSONL or plain transcripts.
|
|
7
|
+
- **Known root manifests** advertised during preview: `backbone.yml`, package/runtime manifests, lockfiles, and language config files from the fixed allowlist in `project-profile.mjs`. Symlinks and files above 1 MiB are ignored. Script bodies are never returned, persisted, or executed.
|
|
7
8
|
|
|
8
|
-
Never read: the home directory, global tool history, other repos,
|
|
9
|
+
Never read: the home directory, global tool history, other repos, arbitrary source files, or unadvertised paths. `preview` shows supplied evidence files, known manifest inventory, sizes, and date window before content is read; the approval token includes manifest size and modification time.
|
|
9
10
|
|
|
10
11
|
## What is redacted (before anything else sees it)
|
|
11
12
|
|
|
@@ -26,8 +27,19 @@ Aggregate snapshots under the git-ignored `.vibekit/reports/tutien/`:
|
|
|
26
27
|
|
|
27
28
|
Never persisted: raw prompts, URLs, secrets, file contents, or unsalted event IDs. `aggregate-only` is the default; excerpts are off by default and, if ever enabled, are redacted and capped to one line.
|
|
28
29
|
|
|
30
|
+
`latest-brief.json` contains only aggregate evidence, safe project slugs, allowlisted stack names, generated validation commands based on script names, story pointers, and composition constraints. It never contains package script bodies, arbitrary manifest values, raw event IDs, or stock response prose.
|
|
31
|
+
|
|
32
|
+
The optional living chronicle uses `.vibekit/reports/tutien/story/`:
|
|
33
|
+
|
|
34
|
+
- `latest-context.json` contains only project slugs, aggregate coverage, disjoint token totals, realm/classification slugs, problem types, progression aggregates, and a 16-hex evidence key.
|
|
35
|
+
- `plot.md` and `chapters/*.md` contain agent-authored fiction derived from approved aggregates and non-secret repository metadata already in task scope.
|
|
36
|
+
- `story-state.json` contains the selected language/style, last chapter number, and consumed evidence keys.
|
|
37
|
+
|
|
38
|
+
Story files must never contain raw prompts, conversation excerpts, commit subjects, author names/emails, raw event IDs, URLs, secret values, or source-file contents. Do not turn a real contributor into a character without explicit user permission. Fictional character names are locally generated and are not identity mappings.
|
|
39
|
+
|
|
29
40
|
## Deletion, retention, reset, export
|
|
30
41
|
|
|
31
42
|
- **Retention:** keep the newest N snapshots; `snapshotsToPrune()` returns the rest as a list to remove.
|
|
32
43
|
- **Delete/reset:** use the repo safe-delete policy — prefer `trash <path>`; never a silent `rm`. Deleting `.vibekit/reports/tutien/` resets all trend history.
|
|
33
44
|
- **Export:** a snapshot is plain JSON; copy the file. It already contains no raw content.
|
|
45
|
+
- **Story export:** copy `story/` only after reviewing the fictional prose for project-sensitive metaphors. The deterministic context remains aggregate-only, but the user's chosen plot may itself be private.
|
|
@@ -68,7 +68,38 @@ A usage record contributes to reported/estimated totals and coverage only when a
|
|
|
68
68
|
|
|
69
69
|
## Runner state
|
|
70
70
|
|
|
71
|
-
`scripts/run-tutien.mjs` executes the actions end-to-end. It stores the session mode and
|
|
71
|
+
`scripts/run-tutien.mjs` executes the actions end-to-end. It stores the session mode and pending single-use approval token in `.vibekit/reports/tutien/state.json`, snapshots under `snapshots/`, the audit ledger as `latest.md`, and the agent handoff as `latest-brief.json`. Preview inspects existence, size, and modification time only; analysis runs only with the matching token for the identical evidence and manifest inventory. The runner never deletes files.
|
|
72
|
+
|
|
73
|
+
`latest-brief.json` uses `tutien-response-brief-v1`. It carries policy state, safe project identity/stack/validation commands, aggregate evidence, classification/progression slugs, bounded findings without event IDs, an optional story pointer, and composition constraints. Its object shape is not a response layout.
|
|
74
|
+
|
|
75
|
+
When `story=on`, runner state also stores the selected `storyLanguage`, `storyStyle`, and `storyFocus` for the current repository. A successful approved analysis writes `.vibekit/reports/tutien/story/latest-context.json`; it does not write creative prose.
|
|
76
|
+
|
|
77
|
+
## Living chronicle schemas
|
|
78
|
+
|
|
79
|
+
`latest-context.json` uses `tutien-story-context-v1` and contains:
|
|
80
|
+
|
|
81
|
+
- a deterministic 16-hex `evidenceKey` derived from aggregate facts;
|
|
82
|
+
- `language`, `style`, `focus`, `policyState`, and `canWriteChapter`;
|
|
83
|
+
- safe project, stack, metadata-source, and generated validation-command slugs plus an aggregate author count;
|
|
84
|
+
- coverage, reported/estimated/unknown token totals, realm/score, problem types, classification slugs, and progression aggregates.
|
|
85
|
+
|
|
86
|
+
It never contains `text`, prompts, commit subjects, event IDs, author identities, file contents, URLs, or classification rationale.
|
|
87
|
+
|
|
88
|
+
`story-state.json` uses `tutien-story-state-v1` with `language`, `style`, contiguous `lastChapter`, and unique `consumedEvidenceKeys`.
|
|
89
|
+
|
|
90
|
+
Each `chapters/NNNN-<localized-xianxia-title>.md` uses YAML frontmatter:
|
|
91
|
+
|
|
92
|
+
```yaml
|
|
93
|
+
---
|
|
94
|
+
schema: tutien-story-chapter-v1
|
|
95
|
+
chapter: 1
|
|
96
|
+
title: "Localized title"
|
|
97
|
+
language: vi
|
|
98
|
+
evidence_key: 0123456789abcdef
|
|
99
|
+
---
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Chapter numbers are contiguous and one evidence key may appear in at most one chapter. `scripts/story-ledger.mjs validate` checks these invariants plus the presence of `plot.md` and agreement with `story-state.json`.
|
|
72
103
|
|
|
73
104
|
## Determinism invariant
|
|
74
105
|
|