corcc 0.3.0__tar.gz

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.
corcc-0.3.0/PKG-INFO ADDED
@@ -0,0 +1,10 @@
1
+ Metadata-Version: 2.4
2
+ Name: corcc
3
+ Version: 0.3.0
4
+ Summary: Chain-of-Reasoning Compiler-Compiler — spoken reasoning + persona-melt gauge
5
+ Requires-Python: >=3.11
6
+ Requires-Dist: chaincompiler-accc==0.3.0
7
+ Requires-Dist: chaincompiler==0.3.0
8
+ Requires-Dist: honeyc==0.3.0
9
+ Requires-Dist: rulecatcher==0.3.0
10
+ Requires-Dist: click
@@ -0,0 +1,16 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "corcc"
7
+ version = "0.3.0"
8
+ description = "Chain-of-Reasoning Compiler-Compiler — spoken reasoning + persona-melt gauge"
9
+ requires-python = ">=3.11"
10
+ dependencies = ["chaincompiler-accc==0.3.0", "chaincompiler==0.3.0", "honeyc==0.3.0", "rulecatcher==0.3.0", "click"]
11
+
12
+ [project.scripts]
13
+ corcc = "corcc.cli:main"
14
+
15
+ [tool.setuptools.packages.find]
16
+ where = ["src"]
corcc-0.3.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,29 @@
1
+ """CORCC — Chain-of-Reasoning Compiler-Compiler.
2
+
3
+ A CoR IS A spoken, paragraphical AC that makes a decision. CORCC is a SYNTAX
4
+ compiler: catch grammar → lint (keep the model writing valid CoR) → compile to a
5
+ markdown file → package as <name>/SKILL.md. Composes ACCC (inner attention
6
+ template). ACCC → CORCC → SCCC.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ __version__ = "0.3.0"
11
+
12
+ from .forge import (
13
+ Persona,
14
+ cor_chain,
15
+ forge_persona,
16
+ inner_template,
17
+ lint,
18
+ outer_template,
19
+ package,
20
+ prime,
21
+ )
22
+ from .notation import BANDIT, DEFAULT, EINSTEIN, FEYNMAN, SEED_PERSONAS, Move, PersonaSpec
23
+
24
+ __all__ = [
25
+ "forge_persona", "Persona", "inner_template", "outer_template",
26
+ "lint", "package", "prime", "cor_chain",
27
+ "Move", "PersonaSpec", "BANDIT", "DEFAULT", "EINSTEIN", "FEYNMAN",
28
+ "SEED_PERSONAS", "__version__",
29
+ ]
@@ -0,0 +1,78 @@
1
+ """corcc — forge personas (inner AC + outer CoR), lint CoR syntax, package."""
2
+ from __future__ import annotations
3
+
4
+ from pathlib import Path
5
+ import tempfile
6
+
7
+ import click
8
+
9
+ from .forge import forge_persona, inner_template, lint, outer_template, package, prime
10
+ from .notation import SEED_PERSONAS
11
+
12
+
13
+ @click.group()
14
+ @click.version_option(message="corcc %(version)s")
15
+ def main() -> None:
16
+ """Chain-of-Reasoning Compiler-Compiler."""
17
+
18
+
19
+ @main.command()
20
+ def demo() -> None:
21
+ """Forge ThinkLikeEinstein, lint CoR syntax, and emit a SKILL.md package."""
22
+ with tempfile.TemporaryDirectory() as tmp:
23
+ db = str(Path(tmp) / "corcc.db")
24
+ persona = forge_persona(SEED_PERSONAS["ThinkLikeEinstein"], db=db)
25
+
26
+ click.echo("══ 1. FORGE — a persona = inner AC (silent) + outer CoR (spoken) ══")
27
+ click.echo(f" forged '{persona.name}' (chain grammar scope={persona.inner.scope})")
28
+
29
+ click.echo("\n══ 2. INNER — attention chain (template for a section / thinking; NOT spoken) ══")
30
+ click.echo(inner_template(persona))
31
+
32
+ click.echo("\n══ 3. OUTER — the CoR the model MUST say (paragraph, ends in a decision) ══")
33
+ click.echo(outer_template(persona))
34
+
35
+ click.echo("\n══ 4. LINT — a well-formed CoR (valid syntax = persona intact) ══")
36
+ good = "[Invariants] ⇒ [ThoughtExperiment] ⇒ [Simplicity] ⇒ |Reframe|"
37
+ v, _ = lint(persona, good)
38
+ click.echo(f" {good}\n → {'clean ✓ (intact)' if not v else 'violations'}")
39
+
40
+ click.echo("\n══ 5. LINT — a malformed CoR (dropped a connector = melting) ══")
41
+ bad = "[Invariants] [ThoughtExperiment] ⇒ |Reframe|"
42
+ v, fixes = lint(persona, bad)
43
+ if v:
44
+ vio, fx = v[0], fixes[0]
45
+ click.echo(f" {bad}\n ✗ {vio.verdict}: expected {vio.expected_token!r}, "
46
+ f"found {vio.found_token!r}; fix: insert {list(fx.candidate_tokens)}")
47
+ else:
48
+ click.echo(" (clean)")
49
+
50
+ click.echo("\n══ 6. PACKAGE — compile the CoR to a publishable <name>/SKILL.md ══")
51
+ path = package(persona, out_dir=tmp)
52
+ click.echo(f" wrote {path}")
53
+ click.echo(" ── SKILL.md ──")
54
+ click.echo("\n".join(" " + ln for ln in path.read_text().splitlines()))
55
+
56
+
57
+ @main.command(name="lint")
58
+ @click.argument("persona_name")
59
+ @click.argument("cor_text")
60
+ def lint_cmd(persona_name: str, cor_text: str) -> None:
61
+ """Syntax-lint a CoR string against a seed persona's chain grammar."""
62
+ import tempfile
63
+ spec = SEED_PERSONAS.get(persona_name)
64
+ if spec is None:
65
+ raise click.ClickException(f"unknown persona {persona_name!r}; have {list(SEED_PERSONAS)}")
66
+ with tempfile.TemporaryDirectory() as tmp:
67
+ persona = forge_persona(spec, db=str(Path(tmp) / "c.db"))
68
+ v, fixes = lint(persona, cor_text)
69
+ if not v:
70
+ click.echo("clean ✓ (valid CoR — persona intact)")
71
+ return
72
+ for vio, fx in zip(v, fixes):
73
+ click.echo(f"✗ {vio.verdict}: expected {vio.expected_token!r}, found {vio.found_token!r}; "
74
+ f"fix: insert {list(fx.candidate_tokens)}")
75
+
76
+
77
+ if __name__ == "__main__":
78
+ main()
@@ -0,0 +1,117 @@
1
+ """CORCC — the CoR Compiler-Compiler. Composes ACCC for the inner template.
2
+
3
+ A CoR IS A spoken, paragraphical AC that makes a decision. Like every *CC, CORCC
4
+ is a SYNTAX compiler — it catches the CoR notation's grammar, LINTS it (so the
5
+ model never writes malformed CoR), compiles it to a markdown file, and packages
6
+ that as `<name>/SKILL.md`. It judges no content.
7
+
8
+ A forged persona carries one chain notation rendered two ways:
9
+ - inner : an attention chain (ACCC) — the silent "how to think" template
10
+ - outer : the spoken CoR paragraph that converges on a DECISION
11
+
12
+ The chain's grammar (forged via ACCC) is what `lint` checks. A clean lint = the
13
+ model is writing valid CoR (persona intact); violations = it drifted out of the
14
+ syntax (melting).
15
+ """
16
+ from __future__ import annotations
17
+
18
+ from dataclasses import dataclass
19
+
20
+ from accc import Language as ACLanguage
21
+ from accc import attention_block, forge as ac_forge
22
+ from accc import gate as ac_gate
23
+ from chaincompiler import write_skill # made FROM CC (CC re-exports APE's write_skill)
24
+
25
+ from .notation import PersonaSpec
26
+ from .paragraph import cor_template, must_say_directive
27
+
28
+
29
+ def cor_chain(spec: PersonaSpec) -> str:
30
+ """The reasoning-move sequence as a Dense Rune-Chain (the shared chain)."""
31
+ foci = " ⇒ ".join(f"[{m.name}]" for m in spec.moves[:-1])
32
+ return f"{foci} ⇒ |{spec.held.name}|"
33
+
34
+
35
+ @dataclass
36
+ class Persona:
37
+ spec: PersonaSpec
38
+ inner: ACLanguage # the attention-chain language (from ACCC); also the lint grammar
39
+ db: str
40
+
41
+ @property
42
+ def name(self) -> str:
43
+ return self.spec.name
44
+
45
+
46
+ def forge_persona(spec: PersonaSpec, *, db: str) -> Persona:
47
+ """Mint a persona: forge the chain grammar via ACCC (ACCC → CORCC composition)."""
48
+ inner = ac_forge(spec.name, [cor_chain(spec)], db=db)
49
+ return Persona(spec=spec, inner=inner, db=db)
50
+
51
+
52
+ def inner_template(persona: Persona) -> str:
53
+ """INNER attention chain — a template for a section / thinking. Not spoken."""
54
+ return attention_block(persona.name, cor_chain(persona.spec))
55
+
56
+
57
+ def outer_template(persona: Persona) -> str:
58
+ """OUTER CoR — the spoken paragraph skeleton that converges on a decision."""
59
+ return cor_template(persona.spec)
60
+
61
+
62
+ def lint(persona: Persona, cor_text: str) -> tuple[list, list]:
63
+ """Syntax-lint a CoR written in the persona's chain notation.
64
+
65
+ This is the only check CORCC makes: is the CoR well-formed? A clean result
66
+ means the model is still writing valid CoR (persona intact); violations mean
67
+ it drifted out of the custom syntax ("melting"). No content is judged.
68
+ """
69
+ return ac_gate(persona.inner, cor_text)
70
+
71
+
72
+ def package(persona: Persona, *, out_dir: str, description: str | None = None):
73
+ """Compile the CoR to a publishable `<name>/SKILL.md` package."""
74
+ spec = persona.spec
75
+ chain = cor_chain(spec)
76
+ # NOTE: no ": " in the default — write_skill (APE) does not YAML-escape the
77
+ # description, and a plain scalar containing ": " emits unparseable frontmatter.
78
+ desc = description or (
79
+ f"Chain-of-reasoning (spoken, ends in a decision) — {spec.blurb}."
80
+ if spec.blurb else "Chain-of-reasoning — spoken reasoning that ends in a decision."
81
+ )
82
+ body = "\n".join([
83
+ "This is a **chain of reasoning (CoR)** — a SPOKEN, paragraphical reasoning chain "
84
+ "that ends in a DECISION. Say it as a paragraph; keep the moves in order.",
85
+ "",
86
+ "## CoR (custom syntax)",
87
+ "```rune",
88
+ chain,
89
+ "```",
90
+ "",
91
+ "## Say it as a paragraph, in order",
92
+ must_say_directive(spec),
93
+ outer_template(persona),
94
+ "",
95
+ "## Inner attention chain (use silently to generate the above)",
96
+ inner_template(persona),
97
+ ])
98
+ return write_skill(spec.name, desc, body, out_dir=out_dir, extra={"kind": "chain-of-reasoning"})
99
+
100
+
101
+ def prime(persona: Persona) -> str:
102
+ spec = persona.spec
103
+ return "\n".join([
104
+ f'# PRIME — persona "{persona.name}"',
105
+ f"({spec.blurb})" if spec.blurb else "",
106
+ "",
107
+ "## Inner attention chain (use silently; a template for this section / your thinking)",
108
+ inner_template(persona),
109
+ "",
110
+ "## Outer chain-of-reasoning (you MUST say this, as a paragraph ending in a decision)",
111
+ must_say_directive(spec),
112
+ outer_template(persona),
113
+ "",
114
+ "## Syntax",
115
+ "Write the CoR in the chain notation above; it is linted — if it is malformed, "
116
+ "fix it before continuing (a malformed CoR = the persona is melting).",
117
+ ])
@@ -0,0 +1,92 @@
1
+ """CoR personas: ordered reasoning MOVES with cue-markers.
2
+
3
+ A CoR (Chain of Reasoning) is the OUTER half of a persona. Unlike an attention
4
+ chain (inner, silent, a template for a section/thinking), a CoR is something the
5
+ model MUST SAY, as a paragraph. Because it is spoken, it is gauge-able: if the
6
+ emitted prose performs the required moves IN ORDER, the persona is intact; if it
7
+ skips or scrambles them, the persona has melted.
8
+
9
+ Each persona is an ordered tuple of Moves. Each Move carries cue-markers — the
10
+ surface phrases that count as evidence the move was performed. The LAST move is
11
+ the convergence (the held conclusion the paragraph must reach).
12
+ """
13
+ from __future__ import annotations
14
+
15
+ from dataclasses import dataclass
16
+
17
+
18
+ @dataclass(frozen=True)
19
+ class Move:
20
+ name: str
21
+ cues: tuple[str, ...]
22
+
23
+
24
+ @dataclass(frozen=True)
25
+ class PersonaSpec:
26
+ name: str
27
+ moves: tuple[Move, ...] # ordered; last move = the held convergence
28
+ blurb: str = ""
29
+
30
+ @property
31
+ def held(self) -> Move:
32
+ return self.moves[-1]
33
+
34
+
35
+ # ── THE DEFAULT persona: the agent IS the bandit ────────────────────────────
36
+ # Einstein/Feynman below are *flavors* — each is a single proven chain, i.e. a
37
+ # ChainConstruct OUTPUT. The DEFAULT persona is the thing that sits ABOVE the
38
+ # flavors and decides whether to construct one at all: the ChainSelector. Given a
39
+ # task it picks an arm —
40
+ # ChainSelect (exploit): reuse a proven / "golden" chain
41
+ # ChainConstruct (explore): assemble a NEW chain
42
+ # This is compoctopus's `router.py` Bandit (Link→Chain→Compiler→Bandit) rendered
43
+ # as a CoR: in ChainCompiler the LLM, shaped by the gate, IS the selector — so the
44
+ # bandit policy is a persona the model reads and performs, not a separate engine.
45
+ BANDIT = PersonaSpec(
46
+ name="BanditChain",
47
+ blurb="frame the task, recall a proven chain, choose exploit (select) vs explore (construct), execute it, record the reward",
48
+ moves=(
49
+ Move("Task", ("the task is", "what's being asked", "given the task",
50
+ "the goal here", "what I need to do")),
51
+ Move("Recall", ("have I done this", "a proven chain", "golden chain",
52
+ "already have one", "seen this before", "in the registry")),
53
+ Move("Decide", ("exploit", "reuse the existing", "explore", "no chain exists yet",
54
+ "reward is high enough", "construct a new", "select vs construct",
55
+ "so I'll select", "so I'll construct")),
56
+ Move("Execute", ("run the chain", "execute it", "apply it", "run it on", "now I run")),
57
+ Move("Reward", ("the result is", "which worked", "record the reward",
58
+ "update the golden", "so the outcome", "the answer is")),
59
+ ),
60
+ )
61
+
62
+
63
+ # The worked example: think like Einstein.
64
+ EINSTEIN = PersonaSpec(
65
+ name="ThinkLikeEinstein",
66
+ blurb="fix the invariant, run a thought experiment, strip to simplest form, reframe the question",
67
+ moves=(
68
+ Move("Invariants", ("invariant", "stays fixed", "regardless of frame",
69
+ "holds in every frame", "what cannot change")),
70
+ Move("ThoughtExperiment", ("imagine", "suppose", "thought experiment",
71
+ "ride alongside", "gedanken", "picture")),
72
+ Move("Simplicity", ("simplest", "strip", "essence", "as simple as possible", "bare")),
73
+ Move("Reframe", ("reframe", "the real question", "actually about",
74
+ "so the question becomes", "reframes")),
75
+ ),
76
+ )
77
+
78
+ # A second persona, to show CORCC mints languages, not one hard-coded shape.
79
+ FEYNMAN = PersonaSpec(
80
+ name="ThinkLikeFeynman",
81
+ blurb="restate plainly, give a concrete example, find where it breaks, then explain simply",
82
+ moves=(
83
+ Move("Plainly", ("in plain terms", "put simply", "what this really says")),
84
+ Move("ConcreteExample", ("for example", "concretely", "take a case", "imagine a")),
85
+ Move("WhereItBreaks", ("breaks down", "fails when", "the catch", "where it goes wrong")),
86
+ Move("ExplainSimply", ("so simply put", "the punchline", "bottom line", "in short")),
87
+ ),
88
+ )
89
+
90
+ # DEFAULT = the selector; the flavors are what it constructs.
91
+ DEFAULT = BANDIT
92
+ SEED_PERSONAS = {p.name: p for p in (BANDIT, EINSTEIN, FEYNMAN)}
@@ -0,0 +1,24 @@
1
+ """Render a CoR persona into the paragraph the model must say.
2
+
3
+ §5 convergence: the fill-in skeleton format lives in the base (`cor_skeleton`); this module renders CORCC's
4
+ PersonaSpec THROUGH that single source (routed via CC, which re-exports it) instead of re-implementing it.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ from chaincompiler import cor_skeleton # made FROM CC (CC re-exports APE's cor_skeleton)
9
+
10
+ from .notation import PersonaSpec
11
+
12
+
13
+ def must_say_directive(spec: PersonaSpec) -> str:
14
+ moves = ", ".join(m.name for m in spec.moves[:-1])
15
+ return (f"State your reasoning as ONE paragraph that performs, in order, {len(spec.moves)} moves: "
16
+ f"{moves}, and finally converges on {spec.held.name}.")
17
+
18
+
19
+ def cor_template(spec: PersonaSpec) -> str:
20
+ """A fill-in paragraph skeleton with one clause per move and its cue — rendered via the base's
21
+ `cor_skeleton` (single source of the format). Each Move contributes its first cue phrase."""
22
+ moves = [m.name for m in spec.moves]
23
+ cues = {m.name: m.cues[0] for m in spec.moves}
24
+ return cor_skeleton(moves, cues)
@@ -0,0 +1,10 @@
1
+ Metadata-Version: 2.4
2
+ Name: corcc
3
+ Version: 0.3.0
4
+ Summary: Chain-of-Reasoning Compiler-Compiler — spoken reasoning + persona-melt gauge
5
+ Requires-Python: >=3.11
6
+ Requires-Dist: chaincompiler-accc==0.3.0
7
+ Requires-Dist: chaincompiler==0.3.0
8
+ Requires-Dist: honeyc==0.3.0
9
+ Requires-Dist: rulecatcher==0.3.0
10
+ Requires-Dist: click
@@ -0,0 +1,14 @@
1
+ pyproject.toml
2
+ src/corcc/__init__.py
3
+ src/corcc/cli.py
4
+ src/corcc/forge.py
5
+ src/corcc/notation.py
6
+ src/corcc/paragraph.py
7
+ src/corcc.egg-info/PKG-INFO
8
+ src/corcc.egg-info/SOURCES.txt
9
+ src/corcc.egg-info/dependency_links.txt
10
+ src/corcc.egg-info/entry_points.txt
11
+ src/corcc.egg-info/requires.txt
12
+ src/corcc.egg-info/top_level.txt
13
+ tests/test_corcc.py
14
+ tests/test_corcc_regressions.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ corcc = corcc.cli:main
@@ -0,0 +1,5 @@
1
+ chaincompiler-accc==0.3.0
2
+ chaincompiler==0.3.0
3
+ honeyc==0.3.0
4
+ rulecatcher==0.3.0
5
+ click
@@ -0,0 +1 @@
1
+ corcc
@@ -0,0 +1,42 @@
1
+ """CORCC tests: forging personas, the inner/outer split, syntax lint, packaging."""
2
+ from __future__ import annotations
3
+
4
+ from pathlib import Path
5
+
6
+ from corcc import cor_chain, forge_persona, inner_template, lint, outer_template, package
7
+ from corcc.notation import EINSTEIN
8
+
9
+
10
+ def test_cor_chain_built_from_moves():
11
+ assert cor_chain(EINSTEIN) == "[Invariants] ⇒ [ThoughtExperiment] ⇒ [Simplicity] ⇒ |Reframe|"
12
+
13
+
14
+ def test_forge_persona_builds_inner_ac(tmp_path: Path):
15
+ p = forge_persona(EINSTEIN, db=str(tmp_path / "c.db"))
16
+ assert p.inner.scope == "ac:ThinkLikeEinstein"
17
+ assert p.inner.rule_count > 0
18
+ assert "Attend" in inner_template(p) # inner = silent template
19
+ assert "Invariants" in outer_template(p) # outer = spoken paragraph skeleton
20
+
21
+
22
+ def test_lint_accepts_well_formed_cor(tmp_path: Path):
23
+ p = forge_persona(EINSTEIN, db=str(tmp_path / "c.db"))
24
+ violations, _ = lint(p, "[Invariants] ⇒ [ThoughtExperiment] ⇒ [Simplicity] ⇒ |Reframe|")
25
+ assert violations == []
26
+
27
+
28
+ def test_lint_flags_malformed_cor(tmp_path: Path):
29
+ p = forge_persona(EINSTEIN, db=str(tmp_path / "c.db"))
30
+ # dropped a connector between the first two moves -> malformed syntax (melting)
31
+ violations, _ = lint(p, "[Invariants] [ThoughtExperiment] ⇒ |Reframe|")
32
+ assert violations, "malformed CoR should be caught by the syntax linter"
33
+
34
+
35
+ def test_package_writes_skill_md(tmp_path: Path):
36
+ p = forge_persona(EINSTEIN, db=str(tmp_path / "c.db"))
37
+ path = package(p, out_dir=str(tmp_path / "skills"))
38
+ assert path.name == "SKILL.md"
39
+ text = path.read_text()
40
+ assert "chain-of-reasoning" in text # frontmatter kind
41
+ assert "DECISION" in text # CoR ends in a decision
42
+ assert cor_chain(EINSTEIN) in text # the custom-syntax chain is in the body
@@ -0,0 +1,24 @@
1
+ """The directive a CoR carries says what the paragraph does (the public repository's bug sweeps, pull requests #1 and #2).
2
+
3
+ It fails on the code before the fix and passes after it.
4
+ """
5
+ from __future__ import annotations
6
+
7
+ from pathlib import Path
8
+
9
+ from corcc import forge_persona, package, prime
10
+ from corcc.notation import BANDIT
11
+ from corcc.paragraph import must_say_directive
12
+
13
+ DIRECTIVE = "State your reasoning as ONE paragraph that performs, in order, 5 moves: "
14
+
15
+
16
+ def test_the_directive_has_its_verb():
17
+ assert must_say_directive(BANDIT).startswith(DIRECTIVE)
18
+
19
+
20
+ def test_every_door_that_writes_the_directive_writes_it_whole(tmp_path: Path):
21
+ persona = forge_persona(BANDIT, db=str(tmp_path / "rules.db"))
22
+ skill = Path(package(persona, out_dir=str(tmp_path / "skills")))
23
+ assert DIRECTIVE in skill.read_text(encoding="utf-8")
24
+ assert DIRECTIVE in prime(persona)