@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.
@@ -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
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "CORDIS review",
4
+ "description": "Review a codebase against the CORDIS paper and apply the fixes that apply."
5
+ }
6
+ }
package/locale/zh.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "CORDIS 审查",
4
+ "description": "按 CORDIS 论文审查代码,并应用适用的修改。"
5
+ }
6
+ }
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.