@maci0/dsh-cordis-review 0.17.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/LICENSE +21 -0
- package/README.md +126 -0
- package/cordis.patch.yml +10 -0
- package/icon.svg +5 -0
- package/lib/check.js +726 -0
- package/lib/cli.js +80 -0
- package/lib/frontmatter.js +308 -0
- package/lib/index.js +29 -0
- package/lib/skills.js +226 -0
- package/lib/types/check.d.ts +39 -0
- package/lib/types/cli.d.ts +10 -0
- package/lib/types/frontmatter.d.ts +46 -0
- package/lib/types/index.d.ts +19 -0
- package/lib/types/skills.d.ts +64 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +68 -0
- package/skills/cordis-doc-review/SKILL.md +207 -0
- package/skills/cordis-review/SKILL.md +210 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* `cordis-review-check [options] [root]`: print closed-form CORDIS tags.
|
|
4
|
+
*
|
|
5
|
+
* One engine (ast-grep, auto-detected) for every tag; without the binary each
|
|
6
|
+
* covered file warns on stderr and yields an LLM-fallback hit.
|
|
7
|
+
*
|
|
8
|
+
* @module dsh-cordis-review/cli
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frontmatter reader for the bundled `SKILL.md` files.
|
|
3
|
+
*
|
|
4
|
+
* Almost every skill header is flat: `key: value`, a quoted scalar, or a
|
|
5
|
+
* `|`/`>` block of same-indent lines. A local reader handles that subset and
|
|
6
|
+
* changes nothing; it returns `undefined` the moment the block contains
|
|
7
|
+
* anything it cannot prove it understood (a nested map, a list, a quoted
|
|
8
|
+
* scalar with an escape, a more-indented or empty line inside a block scalar,
|
|
9
|
+
* a flow collection, a YAML-tag indicator). The caller then loads `yaml`
|
|
10
|
+
* dynamically and re-parses that one file, so the fallback stays the contract
|
|
11
|
+
* and a static `import('yaml')` no longer costs every boot ~11ms of CPU for a
|
|
12
|
+
* mapping it never needed.
|
|
13
|
+
*
|
|
14
|
+
* The fast path may only claim a block whose value is *provably* what `yaml`
|
|
15
|
+
* produces. Anything it cannot prove (a `\r` anywhere in the source, a quoted
|
|
16
|
+
* key, a duplicate key, a `#` in a value, a scalar that has a typed YAML form
|
|
17
|
+
* (`0x10`, `0o17`, `.inf`, `.nan`, `1_000`, `+5`, `-0`, leading zeros), a
|
|
18
|
+
* `+` keep-chomped block scalar) is refused and re-parsed by `yaml`. A false
|
|
19
|
+
* refusal costs one dynamic import; a false claim silently diverges.
|
|
20
|
+
*
|
|
21
|
+
* The delimiter scan stays local: frontmatter with no closing `---` is not
|
|
22
|
+
* frontmatter, and the body is then the whole source.
|
|
23
|
+
*
|
|
24
|
+
* @module dsh-cordis-review/frontmatter
|
|
25
|
+
*/
|
|
26
|
+
/** Parsed frontmatter plus the markdown body that follows it. */
|
|
27
|
+
export interface Frontmatter {
|
|
28
|
+
/** Frontmatter mapping, values as the YAML parser produced them. */
|
|
29
|
+
readonly data: Readonly<Record<string, unknown>>;
|
|
30
|
+
/** Everything after the closing delimiter, or the whole source when absent. */
|
|
31
|
+
readonly body: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Parse leading frontmatter from a markdown document, for the flat subset only.
|
|
35
|
+
* @param source - full file contents.
|
|
36
|
+
* @returns the mapping and body, or `undefined` when this file's block needs
|
|
37
|
+
* the real YAML parser ({@link parseFrontmatterWithYaml}).
|
|
38
|
+
*/
|
|
39
|
+
export declare function parseFrontmatter(source: string): Frontmatter | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Parse leading frontmatter with the `yaml` parser the harness's own filesystem
|
|
42
|
+
* skill provider uses. Loaded dynamically, so a flat header never pays for it.
|
|
43
|
+
* @param source - full file contents.
|
|
44
|
+
* @returns the parsed mapping and the remaining body.
|
|
45
|
+
*/
|
|
46
|
+
export declare function parseFrontmatterWithYaml(source: string): Promise<Frontmatter>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-cordis-review: CORDIS review skills as a DeepSeek Harness plugin.
|
|
3
|
+
*
|
|
4
|
+
* One capability: every bundled `skills/<name>/SKILL.md` becomes a
|
|
5
|
+
* `ctx.skills` provider entry, so each appears as `/<name>` in the composer
|
|
6
|
+
* (DSH's command surface for user-invocable skills). `cordis-review` reviews
|
|
7
|
+
* a codebase against the CORDIS context paradigm (arXiv:2608.25512) and
|
|
8
|
+
* applies the fixes; `cordis-doc-review` writes and repairs the docs.
|
|
9
|
+
*
|
|
10
|
+
* @module dsh-cordis-review
|
|
11
|
+
*/
|
|
12
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
13
|
+
/** Plugin name as it appears in the loader. */
|
|
14
|
+
export declare const name = "cordis-review";
|
|
15
|
+
/**
|
|
16
|
+
* Mount the plugin.
|
|
17
|
+
* @param ctx - the host context.
|
|
18
|
+
*/
|
|
19
|
+
export declare function apply(ctx: Context): void;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The bundled cordis-review skill as a `ctx.skills` provider.
|
|
3
|
+
*
|
|
4
|
+
* Skills are read from this package's `skills/<name>/SKILL.md`, so that file
|
|
5
|
+
* stays the single source of truth for `/cordis-review`.
|
|
6
|
+
*
|
|
7
|
+
* @module dsh-cordis-review/skills
|
|
8
|
+
*/
|
|
9
|
+
import { BUNDLED_SKILL_RANK } from '@deepseek-ai/dsh-skill';
|
|
10
|
+
import type { SkillCandidate, SkillDefinition, SkillInvocationPolicy, SkillLookupOptions, SkillProviderObservation } from '@deepseek-ai/dsh-skill';
|
|
11
|
+
/**
|
|
12
|
+
* Rank matching a harness bundled skill, re-exported from the registry so a
|
|
13
|
+
* project-level or user-level skill of the same name still wins the duplicate.
|
|
14
|
+
*/
|
|
15
|
+
export { BUNDLED_SKILL_RANK };
|
|
16
|
+
/** One parsed bundled skill. */
|
|
17
|
+
interface BundledSkill {
|
|
18
|
+
/** Kebab-case skill name from frontmatter, or the directory name. */
|
|
19
|
+
readonly name: string;
|
|
20
|
+
/** Routing description from frontmatter. */
|
|
21
|
+
readonly description: string;
|
|
22
|
+
/** Extra routing hint from frontmatter, when present. */
|
|
23
|
+
readonly whenToUse?: string;
|
|
24
|
+
/** Resolved invocation controls from the documented frontmatter keys. */
|
|
25
|
+
readonly invocation: SkillInvocationPolicy;
|
|
26
|
+
/** Instruction body with frontmatter removed. */
|
|
27
|
+
readonly content: string;
|
|
28
|
+
/** Remaining frontmatter keys (provider-specific only). */
|
|
29
|
+
readonly metadata: Readonly<Record<string, unknown>>;
|
|
30
|
+
/** Absolute path of the instruction file. */
|
|
31
|
+
readonly path: string;
|
|
32
|
+
/** Absolute path of the skill directory, used as the resource base. */
|
|
33
|
+
readonly directory: string;
|
|
34
|
+
}
|
|
35
|
+
/** Options for {@link createSkillProvider}. */
|
|
36
|
+
interface SkillProviderOptions {
|
|
37
|
+
/** Directory holding one subdirectory per skill. */
|
|
38
|
+
readonly skillsDir: string;
|
|
39
|
+
/** Receives non-fatal discovery problems instead of throwing. */
|
|
40
|
+
readonly onWarn?: (message: string) => void;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Read every valid skill directory under `skillsDir`.
|
|
44
|
+
*
|
|
45
|
+
* A missing directory, a directory without `SKILL.md`, a file whose frontmatter
|
|
46
|
+
* the reader refuses, and a file with a missing description or an invalid
|
|
47
|
+
* invocation key are reported through `onWarn` and skipped: one broken file
|
|
48
|
+
* must not cost the catalog its other skills.
|
|
49
|
+
* @param skillsDir - directory holding one subdirectory per skill.
|
|
50
|
+
* @param onWarn - optional non-fatal problem sink.
|
|
51
|
+
* @param signal - aborts discovery for a caller that no longer wants the result.
|
|
52
|
+
* @returns the parsed skills, sorted by name.
|
|
53
|
+
*/
|
|
54
|
+
export declare function discoverSkills(skillsDir: string, onWarn?: (message: string) => void, signal?: AbortSignal): Promise<readonly BundledSkill[]>;
|
|
55
|
+
/**
|
|
56
|
+
* Build the provider the skill registry mounts.
|
|
57
|
+
* @param options - skills directory and the non-fatal problem sink.
|
|
58
|
+
* @returns a provider whose candidates are summaries and whose bodies come from disk.
|
|
59
|
+
*/
|
|
60
|
+
export declare function createSkillProvider(options: SkillProviderOptions): {
|
|
61
|
+
name: string;
|
|
62
|
+
list(lookup?: SkillLookupOptions): Promise<readonly SkillCandidate[] | SkillProviderObservation>;
|
|
63
|
+
get(candidate: SkillCandidate, lookup?: SkillLookupOptions): Promise<SkillDefinition | undefined>;
|
|
64
|
+
};
|
package/locale/en.json
ADDED
package/locale/zh.json
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@maci0/dsh-cordis-review",
|
|
3
|
+
"version": "0.17.1",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public",
|
|
6
|
+
"registry": "https://registry.npmjs.org/"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"main": "lib/index.js",
|
|
10
|
+
"types": "lib/types/index.d.ts",
|
|
11
|
+
"description": "CORDIS review slash command (/cordis-review) for DeepSeek Harness: review a codebase against arXiv:2608.25512 and apply the applicable fixes.",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"bin": {
|
|
14
|
+
"cordis-review-check": "lib/cli.js"
|
|
15
|
+
},
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./lib/types/index.d.ts",
|
|
19
|
+
"default": "./lib/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
22
|
+
"./locale/*.json": "./locale/*.json",
|
|
23
|
+
"./package.json": "./package.json"
|
|
24
|
+
},
|
|
25
|
+
"dsh": {
|
|
26
|
+
"bundle": {
|
|
27
|
+
"patch": "./cordis.patch.yml"
|
|
28
|
+
},
|
|
29
|
+
"compatibility": {
|
|
30
|
+
"dsh": ">=0.2.0-rc.2 <0.3.0"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"icon.svg",
|
|
35
|
+
"locale/*.json",
|
|
36
|
+
"lib/**/*.js",
|
|
37
|
+
"lib/types/**/*.d.ts",
|
|
38
|
+
"skills",
|
|
39
|
+
"cordis.patch.yml",
|
|
40
|
+
"README.md",
|
|
41
|
+
"LICENSE"
|
|
42
|
+
],
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "bunx --bun tsc -p tsconfig.build.json",
|
|
45
|
+
"test": "bun test",
|
|
46
|
+
"typecheck": "bunx --bun tsc -p tsconfig.json",
|
|
47
|
+
"check": "bun lib/cli.js",
|
|
48
|
+
"test:node": "node --test tests/*.test.*"
|
|
49
|
+
},
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": "^22.19.0 || >=24.0.0"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"@deepseek-ai/dsh-skill": "0.2.1-alpha.1",
|
|
55
|
+
"yaml": "2.9.1"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@deepseek-ai/cordis": "4.0.5-alpha.1",
|
|
59
|
+
"@deepseek-ai/dsh-scope": "0.2.1-alpha.1",
|
|
60
|
+
"@types/node": "^22.20.2",
|
|
61
|
+
"typescript": "^7.0.2"
|
|
62
|
+
},
|
|
63
|
+
"repository": {
|
|
64
|
+
"type": "git",
|
|
65
|
+
"url": "https://github.com/maci0/dsh-cordis-review.git"
|
|
66
|
+
},
|
|
67
|
+
"icon": "./icon.svg"
|
|
68
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cordis-doc-review
|
|
3
|
+
description: >
|
|
4
|
+
Create, repair, or restructure documentation for Cordis plugins, DeepSeek
|
|
5
|
+
Harness subsystems, cookbooks, and package contracts. Use when the user
|
|
6
|
+
asks for CORDIS documentation, a documentation review, a cookbook, a
|
|
7
|
+
subsystem document, or an update to existing technical documentation.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# CORDIS documentation review
|
|
11
|
+
|
|
12
|
+
Create or update documentation that gives a reader one accurate path from a
|
|
13
|
+
Cordis composition to its owned runtime behavior. Deliver documentation edits,
|
|
14
|
+
not a report alone. Treat source code, configuration, and tests as facts;
|
|
15
|
+
never invent API names, lifecycle behavior, commands, or verification results.
|
|
16
|
+
|
|
17
|
+
For DeepSeek Harness and `dsh-*` plugins, read the nearest `AGENTS.md` first.
|
|
18
|
+
When present, apply `docs/AGENTS.md`, `.agents/skills/dsh-doc/SKILL.md`, and
|
|
19
|
+
`.agents/skills/dsh-prose-standard/SKILL.md`. They define repository-specific
|
|
20
|
+
placement, scope, prose, bilingual, and validation rules. This skill supplies
|
|
21
|
+
the Cordis documentation model; repository rules own filenames and gates.
|
|
22
|
+
|
|
23
|
+
## Outcome
|
|
24
|
+
|
|
25
|
+
A complete result has:
|
|
26
|
+
|
|
27
|
+
1. documentation in its owning location;
|
|
28
|
+
2. an accurate topology and lifecycle explanation;
|
|
29
|
+
3. a runnable reader path for common work;
|
|
30
|
+
4. links to detailed owners instead of duplicated detail; and
|
|
31
|
+
5. focused validation or an explicit, concrete reason validation cannot run.
|
|
32
|
+
|
|
33
|
+
Do not add documentation for speculative extension points. Update an existing
|
|
34
|
+
owner when it already owns the fact. Create a new document only when its scope
|
|
35
|
+
cannot fit without mixing audiences or subjects.
|
|
36
|
+
|
|
37
|
+
## Workflow
|
|
38
|
+
|
|
39
|
+
### 1. Establish scope and readers
|
|
40
|
+
|
|
41
|
+
Read the request and nearest documentation rules. Identify the requested
|
|
42
|
+
outcome, target reader, current documents, source owners, configuration rows,
|
|
43
|
+
and tests. If scope is absent, use the named document or current subsystem;
|
|
44
|
+
do not expand to a repository-wide rewrite.
|
|
45
|
+
|
|
46
|
+
Classify each proposed page before writing:
|
|
47
|
+
|
|
48
|
+
- **Tutorial:** ordered route from starting state to an observable outcome.
|
|
49
|
+
- **Reference:** lookup document defining current contracts and behavior.
|
|
50
|
+
- **Cookbook:** narrow repeatable procedure with numbered actions and
|
|
51
|
+
verification.
|
|
52
|
+
- **Subsystem document:** architecture, ownership, lifecycle, seams, and links
|
|
53
|
+
to child documents.
|
|
54
|
+
- **Package README:** package contract, configuration, semantics, limits, and
|
|
55
|
+
extension points.
|
|
56
|
+
|
|
57
|
+
One page has one primary reader goal. Split substantial teaching from lookup
|
|
58
|
+
content. Do not turn a subsystem overview into a catalog of child internals.
|
|
59
|
+
|
|
60
|
+
### 2. Recover runtime truth
|
|
61
|
+
|
|
62
|
+
Trace every statement through its owner before documenting it:
|
|
63
|
+
|
|
64
|
+
1. entry: profile, bundle, config patch, CLI, or public API;
|
|
65
|
+
2. composition: plugin `name`, `inject`, `apply`, and provided service;
|
|
66
|
+
3. lifecycle: registrations, effects, cleanup, unload, replacement, and HMR;
|
|
67
|
+
4. data: input shape, output shape, persistence boundary, error behavior; and
|
|
68
|
+
5. proof: closest tests, examples, and commands that exercise the path.
|
|
69
|
+
|
|
70
|
+
Use code for behavior, tests for exercised guarantees, and generated catalogs
|
|
71
|
+
only for generated facts. State a limitation only when source or tests prove
|
|
72
|
+
it. Link each detail to its lowest owning document.
|
|
73
|
+
|
|
74
|
+
### 3. Model Cordis accurately
|
|
75
|
+
|
|
76
|
+
Explain a Cordis subsystem in terms readers can act on:
|
|
77
|
+
|
|
78
|
+
- **Composition:** which configuration layer mounts it and ordering constraints.
|
|
79
|
+
- **Dependencies:** services declared by `inject`; optional dependencies and
|
|
80
|
+
degraded behavior only when code supports them.
|
|
81
|
+
- **Contributions:** services, tools, events, commands, skills, or config rows
|
|
82
|
+
added through context effects.
|
|
83
|
+
- **Lifecycle:** what happens at apply, replacement, disposal, and reload.
|
|
84
|
+
Registrations are reversible effects, not permanent global mutations.
|
|
85
|
+
- **Ownership:** which component owns each fact, state transition, and cleanup.
|
|
86
|
+
- **Boundaries:** inputs and outputs crossing process, persistence, network, or
|
|
87
|
+
user trust boundaries; validation and failure behavior at each boundary.
|
|
88
|
+
|
|
89
|
+
Never claim `ctx` survives outside its context lifetime. Never describe a
|
|
90
|
+
registration as globally permanent when its effect unwinds on unload. Do not
|
|
91
|
+
promise hot reload, teardown, ordering, or compatibility unless verified.
|
|
92
|
+
|
|
93
|
+
### 4. Write structure before prose
|
|
94
|
+
|
|
95
|
+
Start with title, audience outcome, and table of contents when page size makes
|
|
96
|
+
navigation useful. Put the shortest successful path before advanced detail.
|
|
97
|
+
|
|
98
|
+
Use this default shape when it fits:
|
|
99
|
+
|
|
100
|
+
```md
|
|
101
|
+
# <Subject>
|
|
102
|
+
|
|
103
|
+
<Audience outcome and scope.>
|
|
104
|
+
|
|
105
|
+
## Quick path
|
|
106
|
+
|
|
107
|
+
<Minimal working composition or procedure.>
|
|
108
|
+
|
|
109
|
+
## How it fits
|
|
110
|
+
|
|
111
|
+
<Composition, dependency, and ownership model.>
|
|
112
|
+
|
|
113
|
+
## Lifecycle
|
|
114
|
+
|
|
115
|
+
<Apply, use, dispose/reload behavior.>
|
|
116
|
+
|
|
117
|
+
## Reference
|
|
118
|
+
|
|
119
|
+
<Config, API, events, errors, or limitations.>
|
|
120
|
+
|
|
121
|
+
## Verify
|
|
122
|
+
|
|
123
|
+
<Exact focused command and observable result.>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
A cookbook uses numbered steps and a verification step. A tutorial introduces
|
|
127
|
+
prerequisites before dependent concepts and verifies each milestone. A reference
|
|
128
|
+
uses stable headings and exhaustive coverage only within its own scope.
|
|
129
|
+
|
|
130
|
+
### 5. Edit with ownership discipline
|
|
131
|
+
|
|
132
|
+
Prefer targeted edits to a current canonical document. Keep one owner per
|
|
133
|
+
fact:
|
|
134
|
+
|
|
135
|
+
- source and types own exact API signatures;
|
|
136
|
+
- tests own executable guarantees;
|
|
137
|
+
- package README owns package contract and limits;
|
|
138
|
+
- subsystem docs own architecture and responsibility boundaries;
|
|
139
|
+
- cookbooks own procedures;
|
|
140
|
+
- configuration examples own minimal composition examples.
|
|
141
|
+
|
|
142
|
+
Replace stale claims rather than appending contradictory history. Preserve
|
|
143
|
+
existing navigation, translations, and links unless the repository standard
|
|
144
|
+
requires their update. If an English/Chinese pair exists or local policy
|
|
145
|
+
requires one, update both with aligned headings and equivalent meaning.
|
|
146
|
+
|
|
147
|
+
Write direct prose. Name prerequisites, side effects, limits, error cases, and
|
|
148
|
+
cleanup only where a reader needs them. Remove reasoning transcripts,
|
|
149
|
+
promotional claims, vague adjectives, repeated API restatements, and untested
|
|
150
|
+
commands.
|
|
151
|
+
|
|
152
|
+
### 6. Validate
|
|
153
|
+
|
|
154
|
+
Check every changed link, heading hierarchy, code fence, command, config key,
|
|
155
|
+
and symbol against source. Run the smallest documented Markdown, link, prose,
|
|
156
|
+
or package gate that covers changed files. Run an example command only when its
|
|
157
|
+
side effects and environment are understood.
|
|
158
|
+
|
|
159
|
+
For a documentation claim about runtime behavior, inspect the implementation
|
|
160
|
+
and closest test. For lifecycle prose, inspect the cleanup path. Do not report
|
|
161
|
+
a command as passed unless it ran and passed.
|
|
162
|
+
|
|
163
|
+
## Review checklist
|
|
164
|
+
|
|
165
|
+
Apply all relevant checks and patch every confirmed defect.
|
|
166
|
+
|
|
167
|
+
### Placement and scope
|
|
168
|
+
|
|
169
|
+
- [ ] Page location matches document type and tree ownership.
|
|
170
|
+
- [ ] Page names one subject, target reader, and bounded outcome.
|
|
171
|
+
- [ ] Parent pages describe child responsibility without copying child detail.
|
|
172
|
+
- [ ] Existing canonical document is updated instead of duplicated.
|
|
173
|
+
- [ ] Tutorial, reference, cookbook, subsystem, and README material are not
|
|
174
|
+
materially mixed.
|
|
175
|
+
|
|
176
|
+
### Cordis correctness
|
|
177
|
+
|
|
178
|
+
- [ ] Mounting layer and configuration path are accurate.
|
|
179
|
+
- [ ] `inject` dependencies and optional behavior match source.
|
|
180
|
+
- [ ] Contributions identify their owner and registration mechanism.
|
|
181
|
+
- [ ] Apply, dispose, replacement, and reload claims match actual effects.
|
|
182
|
+
- [ ] State, events, tools, and persistence boundaries name real owners.
|
|
183
|
+
- [ ] No document promises global mutation, leaked context, or unsupported HMR.
|
|
184
|
+
|
|
185
|
+
### Reader usefulness
|
|
186
|
+
|
|
187
|
+
- [ ] Quick path starts from stated prerequisites and reaches an observable end.
|
|
188
|
+
- [ ] Examples are minimal, complete, and use current names.
|
|
189
|
+
- [ ] Reference entries define behavior, failure conditions, and limits needed
|
|
190
|
+
for safe use.
|
|
191
|
+
- [ ] Details link downward to their owner instead of repeating them.
|
|
192
|
+
- [ ] Verification is concrete and proportionate to the change.
|
|
193
|
+
|
|
194
|
+
### Editorial quality
|
|
195
|
+
|
|
196
|
+
- [ ] Headings form a usable hierarchy and links resolve.
|
|
197
|
+
- [ ] Prose states contracts, not author reasoning or marketing.
|
|
198
|
+
- [ ] Facts have evidence in source, tests, configuration, or executed output.
|
|
199
|
+
- [ ] Translation and metadata requirements remain satisfied.
|
|
200
|
+
- [ ] Changed pages meet local word-count and documentation gates.
|
|
201
|
+
|
|
202
|
+
## Completion report
|
|
203
|
+
|
|
204
|
+
Report only changed documents, validated commands with results, and material
|
|
205
|
+
omissions with their trigger. Do not list unconfirmed findings. If no edit is
|
|
206
|
+
needed, state why the existing documentation already passes the applicable
|
|
207
|
+
checklist.
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cordis-review
|
|
3
|
+
description: >
|
|
4
|
+
Review the current codebase against the CORDIS context paradigm
|
|
5
|
+
(arXiv:2608.25512) and implement every applicable fix. Use when the
|
|
6
|
+
user says "cordis review", "review against CORDIS", "spatiotemporal
|
|
7
|
+
composability", or invokes /cordis-review. Targets plugin systems,
|
|
8
|
+
harnesses, and any code that loads, unloads, or depends on components
|
|
9
|
+
at runtime.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# CORDIS review
|
|
13
|
+
|
|
14
|
+
Review this workspace against **A Programming Paradigm for Spatiotemporal
|
|
15
|
+
Composability** (Shi, Zhang, Cui; [arXiv:2608.25512](https://arxiv.org/abs/2608.25512))
|
|
16
|
+
and **implement every applicable fix**. Report-only is failure. Skip a finding
|
|
17
|
+
only when the paper's own system-boundary argument says the effect cannot be
|
|
18
|
+
tracked.
|
|
19
|
+
|
|
20
|
+
**This file is the checklist: start here.** It is the operational form of
|
|
21
|
+
the paper and is sufficient to review and patch; the agent is not required to
|
|
22
|
+
fetch anything before auditing.
|
|
23
|
+
|
|
24
|
+
Paper fetch, if you want the abstract and exact metadata: the **abs page only**,
|
|
25
|
+
<https://arxiv.org/abs/2608.25512> (HTTP 200). Do **not** try the PDF
|
|
26
|
+
(`/pdf/2608.25512`: this harness rejects `application/pdf`) or an HTML
|
|
27
|
+
rendering (`/html/2608.25512v1` is 404: no HTML is published for this
|
|
28
|
+
submission). The abstract is not the checklist: rules come from this file, not
|
|
29
|
+
from a fetched page, and never from memory. The `§` numbers below are cited
|
|
30
|
+
from the paper's section structure and were verified against it; do not
|
|
31
|
+
re-derive or second-guess them mid-review.
|
|
32
|
+
|
|
33
|
+
If the workspace is DeepSeek Harness or a `dsh-*` plugin, also obey that
|
|
34
|
+
repo's Cordis conventions (`AGENTS.md`, `docs/cordis-primer.md`,
|
|
35
|
+
`docs/cordis-tutorial/`). The paper wins on the model; the repo wins on
|
|
36
|
+
names (`ctx.effect`, `inject`, `ctx.get`, `apply`).
|
|
37
|
+
|
|
38
|
+
## Protocol
|
|
39
|
+
|
|
40
|
+
1. **Scope.** Default: the current workspace. A `/cordis-review <path>`
|
|
41
|
+
argument, if present, is the root. Do not wander into unrelated checkouts.
|
|
42
|
+
2. **Get the rules.** Read this file's **Checklist** and **What the paper
|
|
43
|
+
requires** sections: that is the complete rubric, already loaded. If you
|
|
44
|
+
need the paper's abstract or exact metadata, `web_fetch` the abs page
|
|
45
|
+
`https://arxiv.org/abs/2608.25512` (the only URL that works; the PDF is
|
|
46
|
+
rejected and there is no HTML rendering). In DSH / `dsh-*` plugin
|
|
47
|
+
workspaces, also read that repo's `AGENTS.md` and `docs/cordis-primer.md`;
|
|
48
|
+
those are the local naming and convention source of truth.
|
|
49
|
+
3. **Map the runtime.** Find the context object, effect/coeffect primitives,
|
|
50
|
+
component/plugin entrypoints (`apply` / `inject` / `Service`), and the
|
|
51
|
+
loader. In DSH/Cordis that is `ctx`, `ctx.effect` / `ctx.on` / `ctx.set`,
|
|
52
|
+
`inject`, fibers, and the Loader.
|
|
53
|
+
4. **Closed-form pass.** Run this plugin's checker before walking the rest of
|
|
54
|
+
the checklist. From this package root:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
node lib/cli.js [scope]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`bun lib/cli.js [scope]` runs the same file where `node` is not on PATH.
|
|
61
|
+
The package root is the parent of `skills/cordis-review/` (this skill's
|
|
62
|
+
directory). It prints `file:line: tag: message` for `mix-export`, `inject`,
|
|
63
|
+
`toplevel`, and `id` (every tag is one ast-grep query) over JS/TS/TSX,
|
|
64
|
+
Python, and YAML files; other languages are not scanned. Without
|
|
65
|
+
`ast-grep` on PATH each covered file warns on stderr and yields an
|
|
66
|
+
LLM-fallback hit: judge that file against the checklist yourself (that is
|
|
67
|
+
the fallback, not a second scanner). `--help` prints the usage. `leak` /
|
|
68
|
+
`inverse` / `hmr` / `boundary` stay judgment.
|
|
69
|
+
`cordis-check: clean` still means walk the checklist. Exit 2 with
|
|
70
|
+
`cordis-check: cannot read <dir>` lines means those directories were not
|
|
71
|
+
scanned: judge their files yourself or fix the permissions and re-run.
|
|
72
|
+
5. **Audit, then fix.** Walk the checklist below. Each hit is a code change
|
|
73
|
+
unless it is a documented outside-boundary emission. Grep callers of every
|
|
74
|
+
function you touch; fix the shared primitive, not one call site.
|
|
75
|
+
6. **Verify.** One HMR/dispose test per registration you add or repair: dispose
|
|
76
|
+
the contributing fiber, assert the contribution is gone. Run the smallest
|
|
77
|
+
existing test command that covers the files you changed. Re-run the checker.
|
|
78
|
+
|
|
79
|
+
## What the paper requires
|
|
80
|
+
|
|
81
|
+
Two orthogonal properties, local to one component, then lifted to a system of
|
|
82
|
+
interleaved components:
|
|
83
|
+
|
|
84
|
+
- **Temporal composability.** Every context mutation carries an inverse the
|
|
85
|
+
runtime holds. Unload runs those inverses LIFO. A leftover timer, listener,
|
|
86
|
+
registry row, or published service after dispose is a bug.
|
|
87
|
+
- **Spatial composability.** A component declares what it requires
|
|
88
|
+
(coeffects). The runtime classifies every context change against that
|
|
89
|
+
declaration and activates or deactivates the component. A missing provider
|
|
90
|
+
leaves it inactive; it does not crash, and it does not reach around the
|
|
91
|
+
declaration.
|
|
92
|
+
|
|
93
|
+
The **context paradigm** mediates every effect and coeffect through one
|
|
94
|
+
context. Reaching another component's context through a closure, import, or
|
|
95
|
+
global leaks effects out of the owner's lifecycle and coeffects out of its
|
|
96
|
+
`inject` list.
|
|
97
|
+
|
|
98
|
+
The runtime does **not** prove that an inverse actually reverts, or that
|
|
99
|
+
operations published at one key commute. Those are author obligations
|
|
100
|
+
(§5.1.1 effect tracking: "Effect tracking" is the only context-transformation
|
|
101
|
+
primitive, and the runtime does not check the inverse witness; §6.1 "System
|
|
102
|
+
Boundary"). This review discharges them in code.
|
|
103
|
+
|
|
104
|
+
## Checklist
|
|
105
|
+
|
|
106
|
+
One line per finding in the report, then the patch.
|
|
107
|
+
|
|
108
|
+
### Temporal: revertible effects
|
|
109
|
+
|
|
110
|
+
- `leak:` side effect not installed through the context (`setInterval`,
|
|
111
|
+
`addEventListener`, `on()`, `fetch` abort, file watch, process, mutex,
|
|
112
|
+
module-level singleton mutation). Wrap in `ctx.effect(() => { …; return dispose })`
|
|
113
|
+
or the helper that already does (`ctx.on`, `register()` that returns a
|
|
114
|
+
disposer).
|
|
115
|
+
- `inverse:` dispose does not restore the pre-effect state, is not idempotent,
|
|
116
|
+
or is not LIFO with sibling effects. Inverse fires at most once.
|
|
117
|
+
- `toplevel:` work at module load (register, listen, I/O, `new Service`)
|
|
118
|
+
instead of inside `apply(ctx)` / the Service constructor. Move it.
|
|
119
|
+
- `double:` dispose path can run the inverse twice, or never. Guard like
|
|
120
|
+
Cordis `armed`.
|
|
121
|
+
- `foreign-ctx:` effect installed on a context that is not `fiber.ctx`
|
|
122
|
+
(captured parent, global, another plugin's `ctx`). Install on the owner.
|
|
123
|
+
|
|
124
|
+
### Spatial: reactive coeffects
|
|
125
|
+
|
|
126
|
+
- `inject:` required service used as `ctx.foo` without `inject: ['foo']`.
|
|
127
|
+
Declare it. Optional services use `ctx.get('foo')`, never the proxy.
|
|
128
|
+
- `bypass:` dependency reached by import, global, or hard-coded singleton
|
|
129
|
+
instead of the context key. Route through `ctx`.
|
|
130
|
+
- `provide:` published service / registry row not a tracked effect
|
|
131
|
+
(`ctx.set`, `ctx.plugin`, `register` returning a disposer). Make it one.
|
|
132
|
+
- `mix-export:` default-export Service **and** named `apply`/`inject` on the
|
|
133
|
+
same module. Loader keeps one form; mixing drops `inject`. Pick one.
|
|
134
|
+
- `react:` component assumes a coeffect is eternal. It must survive provider
|
|
135
|
+
swap / withdraw (stay inactive until the key returns; do not throw in
|
|
136
|
+
`apply` for a missing optional).
|
|
137
|
+
|
|
138
|
+
### Context paradigm
|
|
139
|
+
|
|
140
|
+
- `mediate:` shared mutable environment written outside `ctx` (process global,
|
|
141
|
+
imported registry, `window.*`, file side-channel used as a bus). Put it on
|
|
142
|
+
a service key.
|
|
143
|
+
- `config:` runtime behavior that belongs in the component's `config` /
|
|
144
|
+
Loader entry is a magic constant or env read inside `apply`. Bind config;
|
|
145
|
+
invalid values fail at load, not later.
|
|
146
|
+
- `isolate:` cross-plugin state sharing that should be a realm (`isolate`)
|
|
147
|
+
or a declared service, implemented as a module singleton.
|
|
148
|
+
|
|
149
|
+
### System boundary (§6.1)
|
|
150
|
+
|
|
151
|
+
- **Inside:** exclusive and restorable → must be a tracked effect.
|
|
152
|
+
- **Outside:** cannot restore (bytes already on the wire, other processes
|
|
153
|
+
writing the file) → do not fake an inverse. Either **withhold** until
|
|
154
|
+
commit or **compensate** with an application-level undo, and say so in a
|
|
155
|
+
one-line comment (`cordis-boundary: emission, compensate by X`).
|
|
156
|
+
- `boundary:` treats an inside location as outside (leaks) **or** invents a
|
|
157
|
+
"cleanup" for an emission it cannot revert (lies). Fix the classification.
|
|
158
|
+
|
|
159
|
+
### Lifecycle / loader
|
|
160
|
+
|
|
161
|
+
- `fiber:` retains a child plugin / subscription past owner dispose.
|
|
162
|
+
Keep the fiber and dispose it in the owner's effect.
|
|
163
|
+
- `hmr:` registration has no dispose-the-fiber test. Add one.
|
|
164
|
+
- `id:` duplicate Loader `id` / plugin name, or a bundle patch that `insert`s
|
|
165
|
+
the same row the profile already has.
|
|
166
|
+
|
|
167
|
+
## DSH / Cordis names
|
|
168
|
+
|
|
169
|
+
Map paper → this stack without renaming the stack:
|
|
170
|
+
|
|
171
|
+
| Paper | Code |
|
|
172
|
+
|---|---|
|
|
173
|
+
| context Γ | `ctx` |
|
|
174
|
+
| revertible effect | `ctx.effect`, `ctx.on`, `register()` → disposer |
|
|
175
|
+
| coeffect declaration | `export const inject = ['…']` |
|
|
176
|
+
| coeffect read | `ctx.foo` (required) / `ctx.get('foo')` (optional) |
|
|
177
|
+
| coeffect provide | `ctx.set` / Service constructor key |
|
|
178
|
+
| component | `export function apply(ctx)` or `class extends Service` |
|
|
179
|
+
| fiber | return value of `ctx.plugin(…)` |
|
|
180
|
+
| inverse accumulator | `fiber.dispose` |
|
|
181
|
+
| loader entry | `cordis.yml` / `cordis.patch.yml` row |
|
|
182
|
+
|
|
183
|
+
Harness conventions that already encode the paper: registrations are
|
|
184
|
+
effects; `ctx.get` for optional services; function plugins named-export
|
|
185
|
+
`name` / `inject` / `Config` / `apply` with **no** default export; every
|
|
186
|
+
registry has an HMR-safety test.
|
|
187
|
+
|
|
188
|
+
## Fixes
|
|
189
|
+
|
|
190
|
+
- Smallest change that restores the invariant. Deletion over a new
|
|
191
|
+
abstraction. No "lifecycle manager" class for one timer.
|
|
192
|
+
- Do not add a framework, a second context type, or a compatibility shim.
|
|
193
|
+
- Do not rewrite working Cordis usage into a parallel effect system.
|
|
194
|
+
- Leave theory, proofs, and comments that are not lying. Code only.
|
|
195
|
+
- If a hit is outside this workspace (vendored Cordis, another repo), record
|
|
196
|
+
it as `out-of-scope:` and do not patch it.
|
|
197
|
+
|
|
198
|
+
## Report (after the patches)
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
CORDIS review: arXiv:2608.25512
|
|
202
|
+
scope: <root>
|
|
203
|
+
fixed:
|
|
204
|
+
- <file>:<line>: <tag> <what>. <what you did>.
|
|
205
|
+
skipped:
|
|
206
|
+
- <file>:<line>: <tag> <what>. <why: boundary | out-of-scope | already-correct>
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
No essay. Empty `fixed` with empty `skipped` means you looked and the
|
|
210
|
+
workspace already holds the invariants; say that in one line.
|