@latysh-development/monolith 0.1.0-alpha.1 → 0.1.0-alpha.3
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/README.md +24 -1
- package/dist/brief/collect.d.ts.map +1 -1
- package/dist/brief/collect.js +6 -2
- package/dist/brief/freshness.d.ts +33 -5
- package/dist/brief/freshness.d.ts.map +1 -1
- package/dist/brief/freshness.js +67 -13
- package/dist/brief/markdown-context.d.ts +22 -0
- package/dist/brief/markdown-context.d.ts.map +1 -0
- package/dist/brief/markdown-context.js +66 -0
- package/dist/brief/story.d.ts +2 -10
- package/dist/brief/story.d.ts.map +1 -1
- package/dist/brief/story.js +21 -7
- package/dist/cli/index.js +12 -0
- package/dist/finalize/cli.d.ts +10 -0
- package/dist/finalize/cli.d.ts.map +1 -0
- package/dist/finalize/cli.js +134 -0
- package/dist/finalize/core.d.ts +110 -0
- package/dist/finalize/core.d.ts.map +1 -0
- package/dist/finalize/core.js +773 -0
- package/dist/finalize/index.d.ts +5 -0
- package/dist/finalize/index.d.ts.map +1 -0
- package/dist/finalize/index.js +2 -0
- package/dist/finalize/proposal.d.ts +97 -0
- package/dist/finalize/proposal.d.ts.map +1 -0
- package/dist/finalize/proposal.js +213 -0
- package/dist/ui/apple-touch-icon.png +0 -0
- package/dist/ui/assets/index-5zXAgig8.css +1 -0
- package/dist/ui/assets/{index-C4NhMaq7.js → index-CQgoMYLM.js} +5 -5
- package/dist/ui/assets/monolith-mark-Ct0ammrU.webp +0 -0
- package/dist/ui/favicon-16x16.png +0 -0
- package/dist/ui/favicon-32x32.png +0 -0
- package/dist/ui/favicon.ico +0 -0
- package/dist/ui/index.html +6 -2
- package/dist/update/cli.d.ts +1 -1
- package/dist/update/cli.d.ts.map +1 -1
- package/dist/update/cli.js +10 -3
- package/dist/update/index.d.ts +9 -0
- package/dist/update/index.d.ts.map +1 -1
- package/dist/update/index.js +50 -1
- package/dist/update/legacy-skills.d.ts +15 -0
- package/dist/update/legacy-skills.d.ts.map +1 -0
- package/dist/update/legacy-skills.js +20 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/templates/default-instance/monolith/context/MONOLITH-CHAT-CONTEXT.md +183 -0
- package/templates/default-instance/monolith/memory/working/active.md +11 -0
- package/templates/default-instance/monolith/skills/finalize-story/SKILL.md +68 -2
- package/dist/ui/assets/index-DMZ7ZvZY.css +0 -1
package/dist/update/cli.js
CHANGED
|
@@ -10,7 +10,7 @@ export const UPDATE_USAGE = `Usage: monolith update [--apply]
|
|
|
10
10
|
|
|
11
11
|
Brings an existing MONOLITH instance up to the current agent integration: a
|
|
12
12
|
stable entry point (<root>/AGENT.md), the idea-capture skill, its routing and the
|
|
13
|
-
pointer in your AI instruction files.
|
|
13
|
+
pointer in your AI instruction files, and an up-to-date finalize-story skill.
|
|
14
14
|
(no flag) Preview: shows the plan, writes nothing.
|
|
15
15
|
--apply Performs the plan: ADD creates a missing MONOLITH file, UPDATE adds
|
|
16
16
|
or refreshes a managed block inside a file of yours.
|
|
@@ -24,6 +24,13 @@ What is written, and what is not:
|
|
|
24
24
|
valid UTF-8 (no encoding is converted) or an unreadable file is CONFLICT: nothing is written there and the plan says how
|
|
25
25
|
to resolve it. SKIP means left alone on purpose (e.g. your own skill).
|
|
26
26
|
- Your existing skills, memory, state.json, ideas and text are never overwritten.
|
|
27
|
+
The one exception: a finalize-story skill byte-identical to a known older
|
|
28
|
+
MONOLITH template (nothing of yours in it) is replaced by the current one. Any
|
|
29
|
+
other finalize-story skill (edited, or the current text in different bytes such
|
|
30
|
+
as CRLF/BOM) is a CONFLICT: it is kept, and its compatibility with the
|
|
31
|
+
Finalization Contract is not verified, even if it mentions \`monolith finalize
|
|
32
|
+
plan\` / \`apply\` (it may still allow finalizing by hand). The integration is
|
|
33
|
+
then INCOMPLETE and --apply exits 2 until the file equals the current template.
|
|
27
34
|
Nothing is executed.
|
|
28
35
|
Instances carry no template version, so state is read from the files. Safe to
|
|
29
36
|
re-run. Not transactional and not coordinated between simultaneous runs: apply
|
|
@@ -64,7 +71,7 @@ function verdict(plan, stale = []) {
|
|
|
64
71
|
const manual = plan.items.filter((i) => i.action === 'CONFLICT').length;
|
|
65
72
|
const broken = plan.chain.filter((c) => !c.ok).length;
|
|
66
73
|
if (pending === 0 && manual === 0 && broken === 0 && stale.length === 0)
|
|
67
|
-
return '
|
|
74
|
+
return 'Agent integration: COMPLETE (the managed components are installed and pass the structural check; how an AI assistant behaves is not verified).';
|
|
68
75
|
const parts = [];
|
|
69
76
|
if (pending > 0)
|
|
70
77
|
parts.push(`${pending} change(s) to apply`);
|
|
@@ -74,7 +81,7 @@ function verdict(plan, stale = []) {
|
|
|
74
81
|
parts.push(`${stale.length} change(s) skipped because the file changed meanwhile`);
|
|
75
82
|
if (broken > 0 && parts.length === 0)
|
|
76
83
|
parts.push(`${broken} consistency check(s) failing`);
|
|
77
|
-
return `
|
|
84
|
+
return `Agent integration: INCOMPLETE (${parts.join(', ')}). A partly installed integration is not active.`;
|
|
78
85
|
}
|
|
79
86
|
export async function runUpdate(args, targetDir = process.cwd()) {
|
|
80
87
|
let apply = false;
|
package/dist/update/index.d.ts
CHANGED
|
@@ -7,6 +7,15 @@
|
|
|
7
7
|
* read from the files themselves):
|
|
8
8
|
* - MONOLITH-owned, created when absent: `<root>/AGENT.md`, the `idea-capture`
|
|
9
9
|
* skill. An existing skill is never overwritten, whatever it contains.
|
|
10
|
+
* - `finalize-story` skill (DOGFOOD-002): created when absent; replaced ONLY when
|
|
11
|
+
* it is byte-identical to a known older MONOLITH template (sha256 list in
|
|
12
|
+
* legacy-skills.ts), so nothing of the user's is lost. Any other content is
|
|
13
|
+
* never replaced and is a CONFLICT (DOGFOOD-005): compatibility with the
|
|
14
|
+
* Finalization Contract is unverified, so the integration cannot be COMPLETE.
|
|
15
|
+
* Mentioning `finalize plan` / `finalize apply` is not evidence of compliance
|
|
16
|
+
* and does not change that; only a byte-identical current template is
|
|
17
|
+
* UNCHANGED. Its content is only classified, never trusted as authority and
|
|
18
|
+
* never executed.
|
|
10
19
|
* - Mixed (user-owned file + MONOLITH text): CLAUDE.md / AGENTS.md /
|
|
11
20
|
* .cursorrules / .windsurfrules, routing-map, skills index. MONOLITH text
|
|
12
21
|
* lives only in checksummed managed blocks (src/managed). A missing block is
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/update/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/update/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAKH,OAAO,EAEL,oBAAoB,EAQpB,KAAK,YAAY,EAClB,MAAM,kBAAkB,CAAC;AAM1B,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,QAAQ,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,CAAC;AAEhF,MAAM,WAAW,UAAU;IACzB,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;IACrB,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wEAAwE;AACxE,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAkHD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAkGrD;AAwCD;;;iKAGiK;AACjK,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAE7D;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,qGAAqG;IACrG,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAUD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,WAAW,CAsCvE;AAED,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
|
package/dist/update/index.js
CHANGED
|
@@ -7,6 +7,15 @@
|
|
|
7
7
|
* read from the files themselves):
|
|
8
8
|
* - MONOLITH-owned, created when absent: `<root>/AGENT.md`, the `idea-capture`
|
|
9
9
|
* skill. An existing skill is never overwritten, whatever it contains.
|
|
10
|
+
* - `finalize-story` skill (DOGFOOD-002): created when absent; replaced ONLY when
|
|
11
|
+
* it is byte-identical to a known older MONOLITH template (sha256 list in
|
|
12
|
+
* legacy-skills.ts), so nothing of the user's is lost. Any other content is
|
|
13
|
+
* never replaced and is a CONFLICT (DOGFOOD-005): compatibility with the
|
|
14
|
+
* Finalization Contract is unverified, so the integration cannot be COMPLETE.
|
|
15
|
+
* Mentioning `finalize plan` / `finalize apply` is not evidence of compliance
|
|
16
|
+
* and does not change that; only a byte-identical current template is
|
|
17
|
+
* UNCHANGED. Its content is only classified, never trusted as authority and
|
|
18
|
+
* never executed.
|
|
10
19
|
* - Mixed (user-owned file + MONOLITH text): CLAUDE.md / AGENTS.md /
|
|
11
20
|
* .cursorrules / .windsurfrules, routing-map, skills index. MONOLITH text
|
|
12
21
|
* lives only in checksummed managed blocks (src/managed). A missing block is
|
|
@@ -28,6 +37,7 @@ import { dirname, join, basename, resolve } from 'path';
|
|
|
28
37
|
import { SafeWriteError, RootContainmentError, createFile, openParent, projectBoundary, readConfigFile, readProjectFile, replaceFile, resolveMonolithRoot, } from '../root/index.js';
|
|
29
38
|
import { TEMPLATES_ROOT, substitute } from '../init/scaffold.js';
|
|
30
39
|
import { listIdeas, ideaStore } from '../ideas/store.js';
|
|
40
|
+
import { FINALIZE_STORY_LEGACY } from './legacy-skills.js';
|
|
31
41
|
import { blockBody, inspectBlock, planAppend, planRefresh, prose, renderBlock } from '../managed/index.js';
|
|
32
42
|
const INSTRUCTION_FILES = ['CLAUDE.md', '.cursorrules', '.windsurfrules'];
|
|
33
43
|
const AI_TOOL_FILE = { claude: 'CLAUDE.md', cursor: '.cursorrules', windsurf: '.windsurfrules' };
|
|
@@ -93,6 +103,42 @@ function blockItem(projectRoot, root, spec) {
|
|
|
93
103
|
}
|
|
94
104
|
}
|
|
95
105
|
}
|
|
106
|
+
const FINALIZE_SKILL_TEMPLATE = 'monolith/skills/finalize-story/SKILL.md';
|
|
107
|
+
/**
|
|
108
|
+
* The `finalize-story` skill against the current template (DOGFOOD-002). A known older template
|
|
109
|
+
* is recognised by exact hash, not by searching text, so a user's file is never "recognised" by
|
|
110
|
+
* a phrase it happens to contain.
|
|
111
|
+
*/
|
|
112
|
+
function finalizeSkillItem(projectRoot, r, vars) {
|
|
113
|
+
const rel = `${r}/skills/finalize-story/SKILL.md`;
|
|
114
|
+
const template = readTemplate(FINALIZE_SKILL_TEMPLATE, vars);
|
|
115
|
+
const effect = 'the finalize-story skill requires the deterministic plan → approval → apply flow and forbids manual finalization';
|
|
116
|
+
const read = readInstanceFile(projectRoot, rel, true);
|
|
117
|
+
if (read.kind === 'unsafe')
|
|
118
|
+
return { path: rel, action: 'CONFLICT', reason: `cannot be read safely (${read.detail}); not inspected or changed` };
|
|
119
|
+
if (read.kind === 'missing')
|
|
120
|
+
return { path: rel, action: 'ADD', reason: 'new file from the current template', content: template, effect };
|
|
121
|
+
const text = read.content;
|
|
122
|
+
if (text === template)
|
|
123
|
+
return { path: rel, action: 'UNCHANGED', reason: 'identical to the current template' };
|
|
124
|
+
const known = FINALIZE_STORY_LEGACY[sha(text)];
|
|
125
|
+
if (known !== undefined) {
|
|
126
|
+
return { path: rel, action: 'UPDATE', reason: `unedited older MONOLITH template (${known}); replace with the current one`, content: template, before: sha(text), effect };
|
|
127
|
+
}
|
|
128
|
+
// Anything else is unverified. Mentioning `finalize plan` / `apply` proves nothing about the rest of the file
|
|
129
|
+
// (it may still allow manual finalization), so there is no heuristic that upgrades trust (DOGFOOD-005).
|
|
130
|
+
// The byte-variant hint below only improves the message; it never changes the verdict or writes.
|
|
131
|
+
const bytesOnly = text.replace(/^/, '').replace(/\r\n/g, '\n').replace(/\n+$/, '') === template.replace(/\n+$/, '');
|
|
132
|
+
const why = bytesOnly
|
|
133
|
+
? 'has the current template text but different bytes (line endings, BOM or trailing newline)'
|
|
134
|
+
: 'differs from the current template and from every known MONOLITH template';
|
|
135
|
+
return {
|
|
136
|
+
path: rel,
|
|
137
|
+
action: 'CONFLICT',
|
|
138
|
+
reason: `${why}: compatibility with the Finalization Contract is not verified (it may still tell an assistant to finalize by hand). Your file is not changed`,
|
|
139
|
+
proposal: `Compare your file with the current template (templates/default-instance/${FINALIZE_SKILL_TEMPLATE} in the monolith package) and merge its "Deterministic Execution" section, or rename ${rel} and re-run \`monolith update --apply\` to get the current skill. Until the file equals the current template, the integration is reported INCOMPLETE.\n`,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
96
142
|
/**
|
|
97
143
|
* Read-only. Throws RootContainmentError when the root/config is unusable and
|
|
98
144
|
* `Error` when the directory is not a MONOLITH instance.
|
|
@@ -135,6 +181,7 @@ export function planUpdate(target) {
|
|
|
135
181
|
skillText = skill.content;
|
|
136
182
|
items.push({ path: skillRel, action: 'SKIP', reason: 'exists and differs from the current template (customized or older); not overwritten' });
|
|
137
183
|
}
|
|
184
|
+
items.push(finalizeSkillItem(pr, r, vars));
|
|
138
185
|
items.push(blockItem(pr, r, {
|
|
139
186
|
id: 'agent',
|
|
140
187
|
rel: `${r}/AGENT.md`,
|
|
@@ -206,6 +253,8 @@ function chainChecks(projectRoot, r, items, skillText) {
|
|
|
206
253
|
const skillPresent = skillItem?.action === 'UNCHANGED' || skillItem?.action === 'SKIP';
|
|
207
254
|
add('skill', skillPresent, 'the idea-capture skill exists', 'the idea-capture skill is missing or unreadable');
|
|
208
255
|
add('skill → CLI', skillPresent && skillText !== null && /monolith idea add/.test(prose(skillText)), 'the skill calls `monolith idea add`', 'the skill does not call `monolith idea add` (a customized skill may have dropped it)');
|
|
256
|
+
const finItem = state(`${r}/skills/finalize-story/SKILL.md`);
|
|
257
|
+
add('finalize skill → CLI', finItem?.action === 'UNCHANGED', 'the finalize-story skill is identical to the current template', 'the finalize-story skill is missing, outdated, unreadable, or not verified to match the current template (a customized one is never assumed compatible)');
|
|
209
258
|
let storage = '';
|
|
210
259
|
try {
|
|
211
260
|
listIdeas(ideaStore(projectRoot));
|
|
@@ -225,7 +274,7 @@ export function integrationComplete(plan) {
|
|
|
225
274
|
}
|
|
226
275
|
/** Apply order: MONOLITH-owned files first, the pointer in the root instruction files last. */
|
|
227
276
|
function rank(item, r) {
|
|
228
|
-
if (item.path.startsWith(`${r}/skills/idea-capture/`))
|
|
277
|
+
if (item.path.startsWith(`${r}/skills/idea-capture/`) || item.path.startsWith(`${r}/skills/finalize-story/`))
|
|
229
278
|
return 0;
|
|
230
279
|
if (item.path === `${r}/AGENT.md`)
|
|
231
280
|
return 1;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Known historic bytes of MONOLITH-owned skills (DOGFOOD-002). An installed skill
|
|
3
|
+
* whose sha256 is listed here is an unedited copy of an older template, so
|
|
4
|
+
* replacing it loses nothing. Anything else is the user's text and is never
|
|
5
|
+
* replaced. Hashes are over the file as `init` wrote it (the skill has no
|
|
6
|
+
* `{{VARS}}`, so nothing was substituted).
|
|
7
|
+
*/
|
|
8
|
+
export declare const FINALIZE_STORY_LEGACY: Readonly<Record<string, string>>;
|
|
9
|
+
/**
|
|
10
|
+
* sha256 of the CURRENT `finalize-story` template. A test pins it: editing the template fails
|
|
11
|
+
* that test until the previous hash is moved into FINALIZE_STORY_LEGACY (so instances that
|
|
12
|
+
* carry the unedited previous text keep updating) and this value is replaced.
|
|
13
|
+
*/
|
|
14
|
+
export declare const FINALIZE_STORY_CURRENT = "9a779ee52327b5dfe64917228eb4dda60bf4901e2ac0cd116339eb70d51d2723";
|
|
15
|
+
//# sourceMappingURL=legacy-skills.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-skills.d.ts","sourceRoot":"","sources":["../../src/update/legacy-skills.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMlE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,qEAAqE,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Known historic bytes of MONOLITH-owned skills (DOGFOOD-002). An installed skill
|
|
3
|
+
* whose sha256 is listed here is an unedited copy of an older template, so
|
|
4
|
+
* replacing it loses nothing. Anything else is the user's text and is never
|
|
5
|
+
* replaced. Hashes are over the file as `init` wrote it (the skill has no
|
|
6
|
+
* `{{VARS}}`, so nothing was substituted).
|
|
7
|
+
*/
|
|
8
|
+
export const FINALIZE_STORY_LEGACY = {
|
|
9
|
+
'7a42dbaad1b0908bad820903e2e22b6e06e06f0ddc44d61d003e3cd5ad36f2c6': 'initial template (manual steps only)',
|
|
10
|
+
'8d7011640de68df5e4aad3f1ff5ecf421d1f7a3b454f3c51f12079cfea743b8a': '0.1.0-alpha.0 / alpha.1; manual steps only, no `monolith finalize`',
|
|
11
|
+
'6c41ea1411d1ff75f0db92a80289662e0725a248f243d3065cda0d0452bae194': 'pre-release development template (DOCSYNC-001)',
|
|
12
|
+
'1b8ee0c357de7edb858e211d8a6ae8af1ae0a77a9289259deac25bbcfb138121': 'pre-release development template (DOCSYNC-003)',
|
|
13
|
+
'31cc69d09ba4996f71b497f1f4454912ab497c1bcd766f4b7b337c34384efd2d': '0.1.0-alpha.2; does not forbid manual finalization',
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* sha256 of the CURRENT `finalize-story` template. A test pins it: editing the template fails
|
|
17
|
+
* that test until the previous hash is moved into FINALIZE_STORY_LEGACY (so instances that
|
|
18
|
+
* carry the unedited previous text keep updating) and this value is replaced.
|
|
19
|
+
*/
|
|
20
|
+
export const FINALIZE_STORY_CURRENT = '9a779ee52327b5dfe64917228eb4dda60bf4901e2ac0cd116339eb70d51d2723';
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const MONOLITH_VERSION = "0.1.0-alpha.
|
|
1
|
+
export declare const MONOLITH_VERSION = "0.1.0-alpha.3";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const MONOLITH_VERSION = '0.1.0-alpha.
|
|
1
|
+
export const MONOLITH_VERSION = '0.1.0-alpha.3';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@latysh-development/monolith",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.3",
|
|
4
4
|
"description": "MONOLITH: Cognitive Infrastructure for AI. An open-source toolkit for observable project state, structured knowledge, and explicit execution governance.",
|
|
5
5
|
"author": "Dmytro Latysh",
|
|
6
6
|
"license": "MIT",
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# MONOLITH — Context for Your AI Working Chat
|
|
2
|
+
|
|
3
|
+
> Paste this document into the AI assistant you use to plan, review and coordinate
|
|
4
|
+
> development (a ChatGPT Project, a Claude Project or conversation, or a similar
|
|
5
|
+
> workspace). It describes the MONOLITH infrastructure installed in this project.
|
|
6
|
+
> It does not describe the project itself: for that, ask the developer for the
|
|
7
|
+
> output of `monolith brief`.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 1. What Is MONOLITH?
|
|
12
|
+
|
|
13
|
+
MONOLITH is **Cognitive Infrastructure for AI**: a local, file-based toolkit that
|
|
14
|
+
gives AI-assisted development an observable project state, structured knowledge
|
|
15
|
+
and explicit execution rules. Everything lives in the repository as Markdown and
|
|
16
|
+
JSON (by default under `{{MONOLITH_ROOT}}/`) and is read and written by the
|
|
17
|
+
`monolith` CLI. It uses no LLM and makes no external network calls.
|
|
18
|
+
|
|
19
|
+
Division of responsibility:
|
|
20
|
+
|
|
21
|
+
| Party | Responsibility |
|
|
22
|
+
|---|---|
|
|
23
|
+
| **MONOLITH** | Stores project memory, protocols and skills; reports project state deterministically; applies controlled changes (finalization, idea capture) only after checks. |
|
|
24
|
+
| **AI agent / assistant** | Reads the context, proposes and performs work, follows the protocols, reports what it did and what it verified. |
|
|
25
|
+
| **Developer (owner)** | Decides scope, approves changes, runs or reviews verification, and is the only authority on what is "done". |
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 2. Core Capabilities
|
|
30
|
+
|
|
31
|
+
All commands run in the project root (the directory where `monolith init` was run;
|
|
32
|
+
it contains `monolith.config.json`). `monolith --help` is the authoritative usage text.
|
|
33
|
+
|
|
34
|
+
| Command | What it does |
|
|
35
|
+
|---|---|
|
|
36
|
+
| `monolith init` | Scaffolds a MONOLITH instance in the current directory. Refuses to run if any file it would write already exists; never overwrites. |
|
|
37
|
+
| `monolith validate` | Static, read-only integrity check of the instance (config, required directories, unreplaced template placeholders). Exit `0` = PASS, `1` = FAIL. Never executes project code. |
|
|
38
|
+
| `monolith brief` | Deterministic, bounded, read-only summary of project state: current story, active missions and checkpoints, mandatory protocols, accepted ADRs, parked ideas. Prints `Completeness` and `Freshness`. Options: `--max-chars N`, `--strict`. |
|
|
39
|
+
| `monolith brief --reconcile` | Read-only report of the evidence behind the `Freshness` verdict: contradictions between state documents, work items referenced in git but not recorded, and what a person should check. Modifies nothing. |
|
|
40
|
+
| `monolith finalize plan --proposal <file>` | Read-only. Checks a JSON finalization proposal against preconditions (`PASS` / `FAIL` / `NOT_VERIFIED`), lists every write target and prints a digest of the exact plan. |
|
|
41
|
+
| `monolith finalize apply --proposal <file> --approve <digest>` | Applies a finalization only if the plan still matches the digest the owner approved. Writes story records in a fixed order; nothing is written if the plan changed. |
|
|
42
|
+
| `monolith mission start\|list\|show\|finish\|checkpoint\|checkpoints` | Records missions and checkpoints in `{{MONOLITH_ROOT}}/state.json`. Experimental; a recommended discipline, not an enforced gate. |
|
|
43
|
+
| `monolith idea add\|list\|show` | Captures a deferred idea without changing the current task, and recalls it later. One Markdown file per idea; ids are not reused (reservations are kept in `ideas/.ids/`). |
|
|
44
|
+
| `monolith update` | For instances created by an older release: previews (and with `--apply` installs) the current agent entry point, the Idea Capture integration and the current `finalize-story` skill. Never overwrites user edits; conflicts are reported, not resolved. Does not add other new template files. |
|
|
45
|
+
| `monolith ui` | Mission Control: a read-only web dashboard on `127.0.0.1` (default port 4173). Does not open a browser. |
|
|
46
|
+
|
|
47
|
+
`monolith status` and `monolith dry-run` exist as names but are **not implemented**.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 3. Project Memory
|
|
52
|
+
|
|
53
|
+
Key files (paths relative to the project root):
|
|
54
|
+
|
|
55
|
+
| File | Role |
|
|
56
|
+
|---|---|
|
|
57
|
+
| `{{MONOLITH_ROOT}}/memory/working/active.md` | The current phase and story. "No active story recorded" means nothing is registered, **not** that the project is complete. |
|
|
58
|
+
| `{{MONOLITH_ROOT}}/memory/working/story-index.md` | Index of finalized stories. |
|
|
59
|
+
| `{{MONOLITH_ROOT}}/context/maps/project-map.md` | Where each kind of knowledge lives in this instance. |
|
|
60
|
+
| `{{MONOLITH_ROOT}}/context/maps/roadmap-index.md` | Phases, stories and their status. |
|
|
61
|
+
| `{{MONOLITH_ROOT}}/context/maps/routing-map.md` | Classifies a request into a task type, and (Table 8) maps each kind of long-term knowledge to its one canonical destination. |
|
|
62
|
+
| `{{MONOLITH_ROOT}}/memory/long-term/` | Decisions, tech debt, architecture principles, execution history. |
|
|
63
|
+
| `{{MONOLITH_ROOT}}/memory/long-term/ideas/` | The Idea Store. Managed only through `monolith idea`; assistants never edit these files. |
|
|
64
|
+
| `{{MONOLITH_ROOT}}/skills/` | Step-by-step procedures (finalize story, current status, idea capture, …) indexed in `skills/INDEX.md`. |
|
|
65
|
+
| `{{MONOLITH_ROOT}}/protocols/` | Rules for boot, cognition modes, governance and execution. |
|
|
66
|
+
| `AGENTS.md` and the AI-tool instruction file (e.g. `CLAUDE.md`) | Instructions for coding agents working inside the repository. |
|
|
67
|
+
|
|
68
|
+
Rule of thumb: knowledge has **one canonical place**. Do not suggest creating new
|
|
69
|
+
directories, registries or templates for something that already has a destination.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 4. Recommended Development Workflow
|
|
74
|
+
|
|
75
|
+
1. **Restore context.** The developer runs `monolith brief` (and, if `Freshness`
|
|
76
|
+
is not `FRESH`, `monolith brief --reconcile`) and shares the output. Treat it
|
|
77
|
+
as the starting point, not as a complete picture.
|
|
78
|
+
2. **Plan the task.** Agree on the goal, scope, out-of-scope items and acceptance
|
|
79
|
+
criteria before implementation starts.
|
|
80
|
+
3. **Implement.** The coding agent works in the repository, following `AGENTS.md`,
|
|
81
|
+
the routing map and the relevant skill. Prefer an isolated branch.
|
|
82
|
+
4. **Test.** Run the project's own typecheck, build and tests. MONOLITH does not
|
|
83
|
+
run them for you.
|
|
84
|
+
5. **Review.** Review the diff and the test output, not the agent's summary of them.
|
|
85
|
+
6. **Update project state.** Keep `active.md`, `roadmap-index.md` and related
|
|
86
|
+
documents in line with what actually happened; use `monolith brief` to spot drift.
|
|
87
|
+
7. **Controlled finalization.** Close a story only with
|
|
88
|
+
`monolith finalize plan` → owner reviews the plan and digest →
|
|
89
|
+
`monolith finalize apply --proposal <file> --approve <digest>`. Never finalize by editing the
|
|
90
|
+
Markdown by hand.
|
|
91
|
+
|
|
92
|
+
Ideas that come up along the way are saved with `monolith idea add` and the
|
|
93
|
+
current task continues unchanged.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 5. Working With AI Assistants
|
|
98
|
+
|
|
99
|
+
**In ChatGPT:** put this document into the Project instructions (or the first
|
|
100
|
+
message of a conversation). Share `monolith brief` output, diffs and test
|
|
101
|
+
results as the work progresses. The chat cannot see the repository; it only
|
|
102
|
+
knows what you paste.
|
|
103
|
+
|
|
104
|
+
**In Claude:** add this document to a Claude Project's knowledge or paste it at
|
|
105
|
+
the start of a conversation. The same rule applies: it sees only what you share.
|
|
106
|
+
|
|
107
|
+
**Working chat vs. coding agent:**
|
|
108
|
+
|
|
109
|
+
| | Working chat (this context) | Coding agent (Claude Code, Codex, Cursor, …) |
|
|
110
|
+
|---|---|---|
|
|
111
|
+
| Sees | Only what you paste | The repository itself |
|
|
112
|
+
| Instructions | This document | `AGENTS.md`, `CLAUDE.md`, `{{MONOLITH_ROOT}}/AGENT.md`, skills, protocols |
|
|
113
|
+
| Role | Architect, consultant, reviewer: plans, questions, reviews, drafts task specifications | Executes: edits files, runs commands and tests |
|
|
114
|
+
| Can change the project | No | Yes, within the scope it is given |
|
|
115
|
+
|
|
116
|
+
A good pattern: the working chat writes a precise task for the coding agent; the
|
|
117
|
+
agent executes it; the developer brings the agent's report and real command output
|
|
118
|
+
back to the chat for review.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## 6. Important Guarantees and Limitations
|
|
123
|
+
|
|
124
|
+
**What the runtime guarantees**
|
|
125
|
+
|
|
126
|
+
- `brief`, `brief --reconcile`, `validate`, `finalize plan`, `idea list|show`,
|
|
127
|
+
`ui` and `update` (without `--apply`) are read-only.
|
|
128
|
+
- Diagnostics are deterministic: the same files and git history produce the same
|
|
129
|
+
output. No LLM and no external network calls (`monolith ui` listens only on
|
|
130
|
+
`127.0.0.1`).
|
|
131
|
+
- User data is protected: `init` never overwrites an existing file;
|
|
132
|
+
`idea add` never overwrites an idea; `update --apply` never changes text you
|
|
133
|
+
edited: it creates missing MONOLITH-owned files, refreshes unedited
|
|
134
|
+
MONOLITH-managed sections and replaces only an unmodified older
|
|
135
|
+
`finalize-story` skill; `finalize apply` writes only
|
|
136
|
+
the exact plan the owner approved by digest. It is not atomic: an interrupted
|
|
137
|
+
run (exit `3`, `INCOMPLETE`) leaves the story not finalized and is completed by
|
|
138
|
+
running `plan` and `apply` again; there is no rollback. Symlinked paths are refused.
|
|
139
|
+
|
|
140
|
+
**What remains a recommendation**
|
|
141
|
+
|
|
142
|
+
- Protocols, skills, cognitive modes and missions are instructions for the AI and
|
|
143
|
+
the developer. Nothing technically stops an assistant from ignoring them or from
|
|
144
|
+
editing Markdown directly.
|
|
145
|
+
- Integrity and governance results used by `finalize` are reports written by the
|
|
146
|
+
assistant. MONOLITH does not run the build or tests; a digest proves the plan did
|
|
147
|
+
not change, not who approved it.
|
|
148
|
+
|
|
149
|
+
**`validate PASS` does not mean the application is correct.** It checks only the
|
|
150
|
+
structure of the MONOLITH instance (configuration, directories, placeholders). It
|
|
151
|
+
does not compile, test, run or analyze your code, and it does not check skill
|
|
152
|
+
content or project state.
|
|
153
|
+
|
|
154
|
+
**`Freshness: UNKNOWN` is not `STALE`.**
|
|
155
|
+
|
|
156
|
+
- `STALE` requires a concrete, named discrepancy: state documents contradict each
|
|
157
|
+
other, or git history references work items no state document mentions.
|
|
158
|
+
- `FRESH` requires positive evidence that nothing changed after the last state update.
|
|
159
|
+
- `UNKNOWN` means there is not enough evidence either way (no git, state never
|
|
160
|
+
committed, commits that name no work item). It is "unverified", not "outdated".
|
|
161
|
+
|
|
162
|
+
`Completeness` is separate: it says whether the brief itself lost information
|
|
163
|
+
while being rendered.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## 7. Working Agreement
|
|
168
|
+
|
|
169
|
+
When assisting with a project that uses MONOLITH:
|
|
170
|
+
|
|
171
|
+
1. **Do not invent project state.** If you have not been shown `brief` output,
|
|
172
|
+
a file or a command result, say that you do not know.
|
|
173
|
+
2. **An AI's claim is not evidence.** "Tests pass" or "done" from any assistant
|
|
174
|
+
(including you) counts only with the actual command output or diff.
|
|
175
|
+
3. **No dangerous Git operations without explicit permission:** no force push,
|
|
176
|
+
reset, rebase of shared branches, branch or worktree deletion, tag, publish or
|
|
177
|
+
merge into the main branch unless the developer asks for it.
|
|
178
|
+
4. **Do not declare work complete without verification:** typecheck, build, tests
|
|
179
|
+
and review, then controlled finalization.
|
|
180
|
+
5. **Do not expand scope on your own.** Propose additional work separately (or as
|
|
181
|
+
an idea via `monolith idea add`); do not fold it into the current task.
|
|
182
|
+
6. **Respect the project's existing instructions.** `AGENTS.md`, the AI-tool
|
|
183
|
+
instruction file, protocols and skills take precedence over general advice.
|
|
@@ -15,6 +15,17 @@ referenced_by:
|
|
|
15
15
|
|
|
16
16
|
# Active Working Memory
|
|
17
17
|
|
|
18
|
+
<!--
|
|
19
|
+
Starting a story: replace "No active story." in the "Current Story" section below with
|
|
20
|
+
a field line at the very start of a line (no indent, list marker or quote), e.g.
|
|
21
|
+
**Story:** <story-id> — <title>
|
|
22
|
+
The first word after "**Story:**" is the story id: letters, digits, "." "_" "-",
|
|
23
|
+
starting with a letter or digit, matched exactly (case-sensitive). `monolith finalize`
|
|
24
|
+
identifies the active story ONLY by this one line. Ids in descriptions, headings,
|
|
25
|
+
code fences or comments do not count; zero or several "**Story:**" lines mean it
|
|
26
|
+
refuses to finalize. Keep the field above any "---" line or heading in that section.
|
|
27
|
+
-->
|
|
28
|
+
|
|
18
29
|
## Active Phase
|
|
19
30
|
|
|
20
31
|
No active phase.
|
|
@@ -22,15 +22,81 @@ Triggered by: "finalize story", "complete story", "mark story done"
|
|
|
22
22
|
|
|
23
23
|
## Pre-conditions
|
|
24
24
|
|
|
25
|
-
- [ ] Active story exists in `memory/working/active.md`
|
|
25
|
+
- [ ] Active story exists in `memory/working/active.md`, identified by exactly one `**Story:** <id>` line in `## Current Story`
|
|
26
26
|
- [ ] All story tasks are complete
|
|
27
27
|
- [ ] No blocking issues open
|
|
28
28
|
|
|
29
29
|
---
|
|
30
30
|
|
|
31
|
+
## Deterministic Execution (`monolith finalize`)
|
|
32
|
+
|
|
33
|
+
Finalization is deterministic and goes through the CLI, in this order:
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
Proposal -> monolith finalize plan -> READY + digest -> Owner Approval
|
|
37
|
+
-> monolith finalize apply -> Verification
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Do not finalize by hand.** Never edit `active.md`, `story-index.md`,
|
|
41
|
+
`execution-history.md`, a story capsule or any other finalization target yourself
|
|
42
|
+
in order to "finalize" a story, and never skip `plan`, the owner's approval or
|
|
43
|
+
`apply`. If `monolith finalize` is unavailable, fails or reports `NOT_READY` /
|
|
44
|
+
`REFUSED` / `INCOMPLETE`, stop, report the output and ask the owner; do not fall
|
|
45
|
+
back to the manual Steps below. This is an instruction to you, not a technical
|
|
46
|
+
barrier: the CLI cannot stop an assistant from editing Markdown directly, so
|
|
47
|
+
following it is your responsibility.
|
|
48
|
+
|
|
49
|
+
Steps 2-6 below only describe what `monolith finalize apply` writes; they are not a
|
|
50
|
+
manual procedure. Step 1 (the integrity and governance results, item 1 below) stays yours.
|
|
51
|
+
|
|
52
|
+
0. **Structural story identity (required before `plan`).** `monolith finalize` knows
|
|
53
|
+
which story is active only from one field line in the `## Current Story` section of
|
|
54
|
+
`memory/working/active.md`, at the very start of the line (no indent, list marker or quote):
|
|
55
|
+
|
|
56
|
+
```markdown
|
|
57
|
+
## Current Story
|
|
58
|
+
|
|
59
|
+
**Story:** S-1 — Example story
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The first word after `**Story:**` is the story id and must equal `proposal.story.id`
|
|
63
|
+
exactly (case-sensitive; letters, digits, `.` `_` `-`, starting with a letter or digit).
|
|
64
|
+
Text after the id is free. Never infer the id from a heading, a description, "Working on X",
|
|
65
|
+
a `Previous:` line, a code fence or a comment: those carry no identity, and zero, duplicate
|
|
66
|
+
or conflicting `**Story:**` lines make `plan` report `NOT_READY` (`expected-state` FAIL) and
|
|
67
|
+
`apply` `REFUSED`. Keep the field above any `---` line or heading in that section.
|
|
68
|
+
If `active.md` predates this field (e.g. `Working on STORY-123`), do not guess and do not
|
|
69
|
+
rewrite it silently: tell the owner the one line that is missing, add it only with their
|
|
70
|
+
consent, then run `plan` again. `expectedCurrentStory` is `{"contains": "<text naming the
|
|
71
|
+
story id>"}` for an active story and `"none"` only when `## Current Story` says "No active
|
|
72
|
+
story."; neither replaces the `**Story:**` field. Do not bypass this by hand-editing the memory
|
|
73
|
+
files or the integrity/governance results to make a check pass.
|
|
74
|
+
1. Complete Step 1 and write `memory/working/integrity-result.md` and
|
|
75
|
+
`memory/working/governance-result.md` for THIS story. Each file needs exactly one
|
|
76
|
+
`**Status:** PASS` (or `FAIL`), exactly one `**Story:** <id> ...` whose first word is
|
|
77
|
+
the story id, and exactly one `**Date:** YYYY-MM-DD` (not after the finalization date,
|
|
78
|
+
at most 7 days before it). Repeated, contradictory or malformed fields, another story,
|
|
79
|
+
or a stale date are never PASS. It is your own report, not an independent check.
|
|
80
|
+
2. Write a finalization proposal (JSON, schema version 1: story, expectedCurrentStory,
|
|
81
|
+
work, summary, keyOutputs, history, optional handoff / docUpdates). Content is
|
|
82
|
+
yours; targets and paths are MONOLITH's. `expectedCurrentStory` is `"none"` or
|
|
83
|
+
`{"contains": "<text naming the story id>"}`; `"any"` does not exist. A story id is
|
|
84
|
+
finalized once: a second proposal for the same id with other wording is a conflict.
|
|
85
|
+
3. `monolith finalize plan --proposal <file>` — read-only. Shows every precondition as
|
|
86
|
+
PASS / FAIL / NOT_VERIFIED, every target, and a digest. Show it to the owner.
|
|
87
|
+
4. Only after the owner approves: `monolith finalize apply --proposal <file> --approve <digest>`.
|
|
88
|
+
Never run `apply` on your own authority and never declare the story finalized
|
|
89
|
+
unless it printed `FINALIZED` or `ALREADY_FINALIZED`. `INCOMPLETE` or `REFUSED`
|
|
90
|
+
means it is NOT finalized: report the output, then re-plan.
|
|
91
|
+
|
|
92
|
+
Documents to keep in sync beyond the memory files go in `docUpdates`; they are written only
|
|
93
|
+
if `monolith.config.json` lists them in `finalization.requiredDocs` / `allowedDocs`.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
31
97
|
## Steps
|
|
32
98
|
|
|
33
|
-
### Step 1 — Verify integrity
|
|
99
|
+
### Step 1 — Verify integrity (yours)
|
|
34
100
|
|
|
35
101
|
Run integrity verification. All checks must pass before proceeding.
|
|
36
102
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.skin-switcher[data-v-76c1c45c]{color:var(--muted);font-size:13px;display:flex;gap:6px;align-items:center}.skin-switcher select[data-v-76c1c45c]{background:var(--surface-2);color:var(--text);border:1px solid var(--control-border);border-radius:4px;padding:2px 6px}:root{--bg: #0e1116;--surface: #161b22;--surface-2: #1d242d;--border: #2b3440;--control-border: #627185;--text: #e6edf3;--muted: #8b98a8;--accent: #58a6ff;--ok: #3fb950;--warn: #d29922;--err: #f85149;--demo: #f0b429;color-scheme:dark}*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--text);font:15px/1.5 system-ui,-apple-system,Segoe UI,Roboto,sans-serif}code,pre{font-family:ui-monospace,SF Mono,Menlo,Consolas,monospace;font-size:.9em}.shell{display:flex;align-items:flex-start;min-height:100vh}.shell-main{flex:1 1 auto;min-width:0}.sidebar{position:sticky;top:0;align-self:flex-start;flex:0 0 240px;width:240px;height:100vh;display:flex;flex-direction:column;background:var(--surface);border-right:1px solid var(--border)}.sidebar-head{padding:14px 16px}.sidebar-panel{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;justify-content:space-between;gap:16px;padding:4px 12px 16px;overflow-y:auto}.sidebar-panel .skin-switcher{margin-top:auto;padding:12px 4px 0;border-top:1px solid var(--border)}.nav-toggle{display:none}.topbar{display:flex;flex-wrap:wrap;align-items:center;gap:12px 24px;padding:10px 20px;min-height:52px;background:var(--surface);border-bottom:1px solid var(--border)}.brand{display:flex;flex-wrap:wrap;gap:0 10px;align-items:baseline}.brand .muted{white-space:nowrap}.brand strong{letter-spacing:.12em}.project{font-weight:600}.topbar-right{margin-left:auto;display:flex;align-items:center;gap:14px}.scenario{color:var(--muted);font-size:13px;display:flex;gap:6px;align-items:center}.scenario select{background:var(--surface-2);color:var(--text);border:1px solid var(--control-border);border-radius:4px;padding:2px 6px}.demo-badge{background:var(--demo);color:#1a1300;font-weight:800;letter-spacing:.1em;padding:4px 12px;border-radius:4px}.nav{display:flex;flex-direction:column;gap:2px}.nav a{color:var(--muted);text-decoration:none;overflow-wrap:anywhere;padding:6px 10px;border-radius:4px}.nav a:hover{color:var(--text);background:var(--surface-2)}.nav a[aria-current=location]{color:var(--text);background:var(--surface-2);font-weight:600;box-shadow:inset 3px 0 0 var(--accent)}.nav a:focus-visible,button:focus-visible,select:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.content{max-width:1100px;margin:0 auto;padding:20px;display:grid;grid-template-columns:minmax(0,1fr);gap:16px}.panel{min-width:0;overflow-wrap:anywhere;background:var(--surface);border:1px solid var(--border);border-radius:6px;padding:16px 20px;scroll-margin-top:16px}.panel h2{margin:0 0 12px;font-size:16px;text-transform:uppercase;letter-spacing:.06em;color:var(--accent)}.panel h3{margin:16px 0 6px;font-size:14px}.panel h4{margin:10px 0 4px;font-size:13px;color:var(--muted)}.facts{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:4px 16px;margin:0}.facts dt{color:var(--muted)}.facts dt,.facts dd{min-width:0}.facts dd{margin:0;overflow-wrap:anywhere}.facts.compact{font-size:13px;margin-top:8px}.cards{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:minmax(0,1fr);gap:10px}.card{min-width:0;overflow-wrap:anywhere;background:var(--surface-2);border:1px solid var(--border);border-radius:4px;padding:10px 14px}.card h3{margin:6px 0 2px;font-size:15px}.card p{margin:4px 0}.card-head{display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap}.status{font-size:12px;padding:1px 8px;border-radius:10px;border:1px solid var(--ok);color:var(--ok)}.steps ul{margin:0;padding-left:20px}.tag{font-weight:400;font-size:11px;color:var(--warn);border:1px solid var(--warn);border-radius:3px;padding:0 6px;margin-left:6px}.roadmap{margin:0;padding:12px;background:var(--surface-2);border-radius:4px;white-space:pre-wrap;overflow-wrap:anywhere}.diag li{min-width:0}.diag{list-style:none;margin:0;padding:0;display:grid;gap:4px}.sev{font-size:11px;text-transform:uppercase;font-weight:700;margin-right:6px}.sev-info .sev{color:var(--accent)}.sev-warning .sev{color:var(--warn)}.sev-error .sev{color:var(--err)}.muted{color:var(--muted)}.empty{color:var(--muted);font-style:italic;margin:0}.unknown{color:var(--warn);font-weight:600;font-style:normal;letter-spacing:.04em}@media(max-width:899px){.shell{display:block}.sidebar{position:sticky;top:0;z-index:2;width:auto;height:auto;max-height:100vh;border-right:0;border-bottom:1px solid var(--border)}.sidebar-head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 12px}.sidebar-panel{display:none;padding-top:4px;max-height:calc(100vh - 56px)}.sidebar.open .sidebar-panel{display:flex}.nav-toggle{display:inline-block}.panel{scroll-margin-top:64px}}@media(max-width:600px){.topbar{padding-left:12px;padding-right:12px}.topbar-right{margin-left:0;width:100%;flex-wrap:wrap;justify-content:space-between}.content{padding:12px}.facts{grid-template-columns:1fr}.facts dd{margin-bottom:6px}}.live-badge{background:#1f6f43;color:#eafff3;font-weight:800;letter-spacing:.1em;padding:4px 12px;border-radius:4px}.live-badge-off{background:var(--surface-2);color:var(--muted, #9aa4b2);border:1px solid var(--border)}.story{white-space:pre-wrap;margin:0;font:inherit}button{background:var(--surface-2);color:var(--text);border:1px solid var(--control-border);border-radius:4px;padding:4px 12px;font:inherit;cursor:pointer}button:disabled{opacity:.5;cursor:default}.section-fade-enter-active{transition:opacity .22s ease-out,transform .22s ease-out}.section-fade-leave-active{transition:opacity .15s ease-in,transform .15s ease-in}.section-fade-enter-from{opacity:0;transform:translateY(8px)}.section-fade-leave-to{opacity:0;transform:translateY(-8px)}@media(prefers-reduced-motion:reduce){.section-fade-enter-active,.section-fade-leave-active{transition:none}.section-fade-enter-from,.section-fade-leave-to{opacity:1;transform:none}}:root[data-skin=cosmic-glass]{--bg: #080a1e;--surface: rgba(12, 16, 40, .74);--surface-2: rgba(30, 34, 76, .62);--border: rgba(190, 200, 255, .2);--control-border: rgba(204, 212, 255, .52);--text: #f1f4ff;--muted: #b8c3df;--accent: #b4a9ff;--ok: #5fd68a;--warn: #f0c040;--err: #ff8a85;--demo: #f0b429;--glass-dense: rgba(9, 12, 32, .86);--glass-edge: inset 0 1px 0 rgba(255, 255, 255, .07);--glass-shadow: 0 8px 32px rgba(2, 3, 14, .45);--glass-blur: blur(14px) saturate(1.15);background:var(--bg)}:root[data-skin=cosmic-glass] body{background:transparent;isolation:isolate}:root[data-skin=cosmic-glass] body:before{content:"";position:fixed;top:0;bottom:0;right:0;left:-14vw;z-index:-1;pointer-events:none;background:linear-gradient(180deg,#080a1e00,#080a1e33 60%,#080a1e99),url(./cosmic-glass-bg-Dwx47zPu.webp) 24% 0 / cover no-repeat,var(--bg)}:root[data-skin=cosmic-glass] .sidebar{background:#080b2080;-webkit-backdrop-filter:blur(4px) saturate(1.1);backdrop-filter:blur(4px) saturate(1.1);border-right-color:var(--border);box-shadow:1px 0 #968cff14,6px 0 28px #02030e59}:root[data-skin=cosmic-glass] .brand strong{color:var(--text);letter-spacing:.16em}:root[data-skin=cosmic-glass] .brand .muted{font-size:13px}:root[data-skin=cosmic-glass] .nav a{color:var(--muted);border-left:2px solid transparent;border-radius:0 6px 6px 0}:root[data-skin=cosmic-glass] .nav a:hover{color:var(--text);background:#968cff29;border-left-color:var(--accent)}:root[data-skin=cosmic-glass] .nav a[aria-current=location]{color:var(--text);background:linear-gradient(90deg,#968cff42,#968cff14);border-left-color:#d3ccff;box-shadow:none}:root[data-skin=cosmic-glass] .sidebar-panel .skin-switcher{border-top-color:var(--border)}:root[data-skin=cosmic-glass] .topbar{background:#080b20a8;-webkit-backdrop-filter:blur(12px) saturate(1.1);backdrop-filter:blur(12px) saturate(1.1);border-bottom-color:var(--border);box-shadow:0 6px 24px #02030e4d}:root[data-skin=cosmic-glass] .project{font-size:16px;letter-spacing:.01em}:root[data-skin=cosmic-glass] .live-badge{background:#14532f;color:#eafff3;border:1px solid #5fd68a}:root[data-skin=cosmic-glass] .live-badge-off{background:var(--glass-dense);color:var(--muted);border-color:var(--border)}:root[data-skin=cosmic-glass] .demo-badge{border:1px solid #ffd978}:root[data-skin=cosmic-glass] .panel{background:var(--surface);-webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);border-radius:10px;box-shadow:var(--glass-edge),var(--glass-shadow);padding:18px 22px}:root[data-skin=cosmic-glass] .panel h2{font-size:14px;letter-spacing:.08em;font-weight:700;padding-bottom:8px;margin-bottom:14px;border-bottom:1px solid var(--border)}:root[data-skin=cosmic-glass] .panel h3{font-size:15px;font-weight:650}:root[data-skin=cosmic-glass] .card{background:var(--surface-2);border-radius:8px;box-shadow:var(--glass-edge);line-height:1.55}:root[data-skin=cosmic-glass] .facts dt{font-size:13px}:root[data-skin=cosmic-glass] .roadmap,:root[data-skin=cosmic-glass] .story{background:var(--glass-dense);border-radius:8px;line-height:1.6}:root[data-skin=cosmic-glass] .roadmap{border:1px solid var(--border)}:root[data-skin=cosmic-glass] .status{background:#5fd68a1f}:root[data-skin=cosmic-glass] .tag{background:#f0c0401a}:root[data-skin=cosmic-glass] button,:root[data-skin=cosmic-glass] select{background:var(--glass-dense);border-color:var(--control-border)}:root[data-skin=cosmic-glass] button:hover:not(:disabled){border-color:var(--accent);background:#3c3882b3}:root[data-skin=cosmic-glass] button:disabled{opacity:1;color:#8f9abb;border-style:dashed;cursor:not-allowed}:root[data-skin=cosmic-glass] a:focus-visible,:root[data-skin=cosmic-glass] button:focus-visible,:root[data-skin=cosmic-glass] select:focus-visible{outline:2px solid #d3ccff;outline-offset:2px;box-shadow:0 0 0 4px #9a8cff59}@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))){:root[data-skin=cosmic-glass]{--surface: rgba(12, 16, 40, .92);--surface-2: rgba(26, 30, 70, .92)}:root[data-skin=cosmic-glass] .sidebar,:root[data-skin=cosmic-glass] .topbar{background:#080b20f2}}@media(prefers-reduced-motion:no-preference){:root[data-skin=cosmic-glass] .nav a,:root[data-skin=cosmic-glass] button{transition:background-color .15s,border-color .15s,color .15s}}@media(max-width:899px){:root[data-skin=cosmic-glass] body:before{left:0;background:linear-gradient(180deg,#080a1e00,#080a1e33 55%,#080a1e8c),url(./cosmic-glass-bg-Dwx47zPu.webp) 16% 0 / cover no-repeat,var(--bg)}:root[data-skin=cosmic-glass] .sidebar{background:#080b20d1;border-bottom-color:var(--border)}:root[data-skin=cosmic-glass] .panel{padding:14px 16px;background:#0c102899}}
|