Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .cursor/skills/laconic/agents/gemini.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ For the rest of this session, follow these rules in every response. The harness
4. Number multi-step work, with one bounded action per step.
5. Finish the current issue before raising a new one.
6. In multi-step work, say which steps are done and which comes next, using my numbering; do not mark a step done unless it is.
7. For errors, state the cause and the fix.
7. State errors plainly. Give the error, the known cause and the fix or the next check that would find the cause, with no 'Uh oh'.
8. Give estimates in concrete units, and only with a basis; otherwise say the time is unknown and what it depends on. Do not substitute typical ranges or industry figures.
9. Group long lists and rank them; never drop a relevant item when completeness matters.
10. No preamble, recap or closing pleasantries. End with one next action only when I must act.
Expand Down
13 changes: 13 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
# The pinned CLIs behind the load checks; see .github/ci/README.md.
- package-ecosystem: npm
directories:
- /.github/ci/claude-code
- /.github/ci/pi
schedule:
interval: weekly
14 changes: 3 additions & 11 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,13 @@
- [ ] **Autonomous agent-authored:** an agent planned and produced most of the substantive change.
- [ ] **Hybrid:** a human and one or more agents both made substantive contributions.

**Agent/tool and model/version:** <!-- Write “None” for human-authored PRs. -->
**Agent/tool and model/version:** <!-- Write 'None' for human-authored PRs. -->

**Agent contribution:** <!-- Planning, code, tests, docs, review or other work. -->

**Human verification:** <!-- What the submitting human personally reviewed and ran. -->

**Known limitations or uncertain results:** <!-- Write “None known” only after review. -->

## Labels

**Target label:** <!-- Select exactly one: Target:Integrations, Target:Evals, Target:Rules or Target:Docs. -->

**Author label:** <!-- Select exactly one: Author:Human, Author:Hybrid or Author:AI. -->

**Workflow labels:** <!-- Add applicable labels: bug, enhancement, issue, question or duplicate. -->
**Known limitations or uncertain results:** <!-- Write 'None known' only after review. -->

## Safety and side effects

Expand All @@ -34,7 +26,7 @@

**Side effects, permissions, network access and cost:**

<!-- State “None” when applicable; otherwise describe exact scope and rollback. -->
<!-- State 'None' when applicable; otherwise describe exact scope and rollback. -->

## Compatibility

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ jobs:
actions: read # Required for Claude to read CI results on PRs
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
fetch-depth: 1

- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@v1
uses: anthropics/claude-code-action@6d5ae526d25ce88daa2200be073e1a373167f064 # v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/cursor-skill-sync.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- name: Fail if the .cursor copy differs from skills
run: |
diff -r skills .cursor/skills || {
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/laconic-check-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
shell: bash
working-directory: tools/laconic-check
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Check the tag matches the crate version
Expand Down Expand Up @@ -68,7 +68,7 @@ jobs:
tar -czf "../$name.tar.gz" ${{ matrix.binary }}
cd .. && shasum -a 256 "$name.tar.gz" > "$name.tar.gz.sha256"
fi
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: laconic-check-${{ matrix.target }}
path: |
Expand All @@ -83,7 +83,7 @@ jobs:
permissions:
contents: write
steps:
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
path: dist
merge-multiple: true
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/laconic-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
run:
working-directory: tools/laconic-check
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Format, lint and test
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pi-load-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- uses: actions/setup-node@v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 22
- name: Install Pi
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/plugin-load-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ jobs:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- uses: actions/setup-python@v5
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.x"
- name: Test native hook implementations
Expand All @@ -37,7 +37,7 @@ jobs:
load:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Install Claude Code
Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- uses: actions/setup-python@v5
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.x"
# Without the binary, tests/test_mcp_server.py would skip.
- name: Build laconic-check
run: cargo build --locked --manifest-path tools/laconic-check/Cargo.toml
- name: Unit tests
run: python -m unittest discover -s tests -v
- name: Validate evaluation cases
Expand Down
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ Agents can access the complete project by reading repository-relative files afte
| OpenCode | `.opencode/` | Auto-discovered plugin and command entry points for V1 (1.18.29+) and V2. |
| Other runtimes | `qwen-extension.json`, `kimi.plugin.json`, `gemini-extension.json`, `GEMINI.md`, `plugin.json` | Qwen, Kimi, Gemini and additional plugin metadata. |
| Writing references | `skills/laconic-prose/references/` | Writing, editing and audit modes, patterns, venues, Style Manual rules and regression cases. |
| Documentation | `README.md`, `INSTALL.md` | User-facing overview and installation. |
| Documentation | `README.md`, `INSTALL.md`, `CHANGELOG.md`, `SECURITY.md` | User-facing overview, installation, changes and vulnerability reporting. |
| Verification | `tests/`, `scripts/` | Unit tests, compatibility checks and evaluation tooling. |
| Contribution workflow | `CONTRIBUTING.md`, `.github/pull_request_template.md` | Authorship, labels, safety, review and PR requirements. |
| Contribution workflow | `CONTRIBUTING.md`, `.github/pull_request_template.md` | Authorship, issues, safety, review and PR requirements. |

## Runtime entry points

Expand Down
85 changes: 85 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Changelog

This file follows the shape of [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and is built from `git log`. The plugin and `laconic-check` are versioned separately. Dates are commit dates. Numbers in brackets are pull requests.

The manifests still declare plugin 0.5.0 and `Cargo.toml` still declares `laconic-check` 0.2.0, so a build from `main` carries those versions plus the Unreleased changes. Only `v0.4.1` and `laconic-check-v0.1.0` are tagged; neither plugin 0.5.0 nor `laconic-check` 0.2.0 has a tag or release.

## [Unreleased]

### Plugin: added

- Warn when always-on mode cannot locate the plugin (#18).
- Run the full Python test suite and eval validation in CI (#19).
- Run eval model calls in parallel with `--jobs` (#11).
- Benchmark Laconic against `humanizer` and `avoid-ai-writing` (#12).
- A revisit trigger for each shortcut marker (#24).
- A README badge row, CodeQL, `CITATION.cff` and `llms.txt` (#37).

### Plugin: changed

- Make Laconic a full replacement for stop-slop and No AI Slop.
- Forbid typical-range estimates in place of evidence.
- Move the compact rule's mechanics into a before-sending checklist (#34).
- Relicense under FSL-1.1-ALv2 (#25), replacing the Apache-2.0 licence adopted the same day (#22).
- Point repository links at EquityBot (#31).

### Plugin: fixed

- Validate eval inputs and record requested model metadata (#20).
- Make hook trimming linear (#29).

### Plugin: security

- Pin CI agent installs and disable lifecycle scripts (#28).
- Keep scenario prompts out of Claude CLI arguments and reject model values that could become options (#30).

### laconic-check: added

- Flag unnecessary hyphens (#13).
- Report protected items an edit added, failing on them only with `--strict` (#26).
- Report dropped quantifiers, modals and bounds in `preserve` (#35).

### laconic-check: fixed

- Catch prose patterns across wrapped Markdown lines (#16).
- Stop date checks from joining separate clauses (#17).
- Make dictionary parsing linear (#29).
- Stop flagging commas that join 2 clauses as serial commas (#36).

## [laconic-check 0.2.0] - 2026-10-20

### Added

- Flag staged contrasts and reveal questions (#10).

## [laconic-check 0.1.0] - 2026-10-20

### Added

- The `lint` and `preserve` commands (#2).
- The MCP server and seeded-fault measurement.
- Stock-phrase linting (#5).
- Flags for mismatched weekdays (#6).
- Prebuilt binaries published on a release tag (#8).

### Changed

- Make the serial-comma rule precise enough to act on (#7).

## [plugin 0.5.0] - 2026-10-19

### Changed

- Turn the i-have-adhd fork into Laconic: concise, answer-first output in correct Australian English, with the No AI Slop prose skill merged into the response rules.
- Rename every adapter, hook, flag, manifest, test and doc to `laconic`.

### Removed

- The stale translations, upstream eval results and logo.

For versions before 0.5.0, see the history from tag `v0.4.1`.

[Unreleased]: https://github.com/EquityBot/laconic/commits/main
[laconic-check 0.2.0]: https://github.com/EquityBot/laconic/commit/b633217
[laconic-check 0.1.0]: https://github.com/EquityBot/laconic/releases/tag/laconic-check-v0.1.0
[plugin 0.5.0]: https://github.com/EquityBot/laconic/commit/3eb0a03
10 changes: 3 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,11 @@ For autonomous-agent or hybrid contributions, disclose the agent or tool and mod

The submitting human remains accountable for the full diff. Before submission, read the changed files, remove unrelated generated changes and verify the claims in the PR description.

## Labels
## Issues and labels

Use one label from each applicable group:
Open an issue for a bug, a feature proposal or a question. Report suspected vulnerabilities privately, as `SECURITY.md` describes, not in an issue.

- **Target:** `Target:Integrations` for a CLI integration, `Target:Evals` for evaluation scripts, `Target:Rules` for skill rules, or `Target:Docs` for documentation and translations.
- **Author:** `Author:Human`, `Author:Hybrid` or `Author:AI`, matching the authorship category above.
- **Workflow:** `bug` for defects, `enhancement` for new features, `issue` for general issue tracking, `question` when more information is needed, or `duplicate` when the issue or PR already exists.

Choose the labels that describe the change; do not use labels as a substitute for the PR description or provenance disclosure. Use `issue` only when no more specific workflow label applies.
Labels are optional and help triage: `bug` for defects, `enhancement` for new features, `documentation` for documentation, `question` when more information is needed and `duplicate` when the issue or PR already exists. A label does not replace the PR description or provenance disclosure.

## Scope and reviewability

Expand Down
2 changes: 1 addition & 1 deletion INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ rm ~/.gemini/commands/laconic.toml # command route
<details>
<summary><strong>GitHub Copilot (VS Code and Copilot CLI)</strong></summary>

Copilot reads Agent Skills natively: the same `SKILL.md`, no conversion. It scans `.github/skills/`, `.claude/skills/` and `.agents/skills/` in the project, and `~/.copilot/skills/`, `~/.claude/skills/`, and `~/.agents/skills/` globally.
Copilot reads Agent Skills natively: the same `SKILL.md`, no conversion. It scans `.github/skills/`, `.claude/skills/` and `.agents/skills/` in the project, and `~/.copilot/skills/` and `~/.agents/skills/` globally. VS Code also scans `~/.claude/skills/`; GitHub's Copilot CLI documentation does not list that path.

### Install

Expand Down
31 changes: 31 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Security policy

Laconic runs code on your machine: its hooks and plugins start with your coding agent, and its MCP server launches a local binary. Please report suspected vulnerabilities privately.

## Report a vulnerability

Use GitHub's private vulnerability reporting: open the [Security tab](https://github.com/EquityBot/laconic/security) and choose 'Report a vulnerability'. If that option is not shown, private reporting is switched off for now: keep the details private and check back later. Do not open a public issue or PR for a suspected vulnerability.

Include the affected file or command, the commit or release, the steps to reproduce and the impact you expect.

Laconic has one maintainer, so handling is best effort and no response or fix time is guaranteed. A confirmed vulnerability is fixed on `main` as soon as the maintainer can manage and disclosed in a GitHub security advisory. Tell us in your report if you want credit.

## Supported versions

Only `main` is supported. Fixes land on `main` and reach the `laconic-check` binaries only through a later [release](https://github.com/EquityBot/laconic/releases). No published binary, including 0.1.0, will be patched or reissued, and no release date is promised.

## In scope

- Hooks in `hooks/`, which run when an agent session starts.
- Plugins and extensions in `.opencode/plugins/` and `extensions/`.
- `tools/laconic-check`: the CLI, `mcp/server.mjs` and the binaries on GitHub Releases.
- Install, update and uninstall commands in `INSTALL.md` that do more than they state.
- `scripts/` and `.github/workflows/`, where untrusted input could run code or expose a secret.
- Skill and rule text that tells an agent to do anything the safety list in `CONTRIBUTING.md` forbids, such as reading credentials or bypassing confirmation.

## Out of scope

- Vulnerabilities in the agent runtimes, models or third-party packages themselves. Report those to their vendors.
- A model that ignores or misapplies the rules.
- Findings `laconic-check` misses or flags wrongly, which are ordinary bugs unless they run code or expose data.
- Upstream projects Laconic derives from, including i-have-adhd.
2 changes: 1 addition & 1 deletion skills/laconic/agents/gemini.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ For the rest of this session, follow these rules in every response. The harness
4. Number multi-step work, with one bounded action per step.
5. Finish the current issue before raising a new one.
6. In multi-step work, say which steps are done and which comes next, using my numbering; do not mark a step done unless it is.
7. For errors, state the cause and the fix.
7. State errors plainly. Give the error, the known cause and the fix or the next check that would find the cause, with no 'Uh oh'.
8. Give estimates in concrete units, and only with a basis; otherwise say the time is unknown and what it depends on. Do not substitute typical ranges or industry figures.
9. Group long lists and rank them; never drop a relevant item when completeness matters.
10. No preamble, recap or closing pleasantries. End with one next action only when I must act.
Expand Down
26 changes: 26 additions & 0 deletions tests/test_ci_installs.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,32 @@ def test_load_checks_do_not_retain_checkout_credentials(self):
step = checkout.split("\n - ", 1)[0]
self.assertIn("persist-credentials: false", step)

def test_workflow_actions_are_pinned_to_full_commit_shas(self):
workflows = (ROOT / ".github/workflows").iterdir()
for path in sorted(p for p in workflows if p.suffix in (".yml", ".yaml")):
text = path.read_text(encoding="utf8")
for use in re.findall(r"^\s*(?:- )?uses:\s*(.+?)\s*$", text, re.M):
with self.subTest(workflow=path.name, uses=use):
self.assertRegex(use, r"^[\w./-]+@[0-9a-f]{40} # v\d")

def test_dependabot_covers_actions_and_every_ci_lockfile(self):
# The suite has no YAML parser, so match each line exactly, block by block.
config = (ROOT / ".github/dependabot.yml").read_text(encoding="utf8")
self.assertRegex(config, r"(?m)^version: 2$")
self.assertRegex(config, r"(?m)^updates:$")
pieces = re.split(r"(?m)^ - package-ecosystem: (\S+)$", config)[1:]
blocks = dict(zip(pieces[::2], pieces[1::2]))
self.assertEqual({"github-actions", "npm"}, set(blocks))
for ecosystem, block in blocks.items():
with self.subTest(ecosystem=ecosystem):
self.assertRegex(block, r"(?m)^ schedule:\n interval: \w+$")
self.assertRegex(blocks["github-actions"], r"(?m)^ directory: /$")
lockfiles = sorted((ROOT / ".github/ci").glob("*/package-lock.json"))
self.assertTrue(lockfiles)
for lock in lockfiles:
with self.subTest(directory=lock.parent.name):
self.assertRegex(blocks["npm"], rf"(?m)^ - /\.github/ci/{lock.parent.name}$")


if __name__ == "__main__":
unittest.main()
Loading
Loading