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: 2 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ External rule importers are welcome, but keep generated third-party output out o
- Add importer tests with small fixtures instead of downloading upstream lists during tests.
- Preserve `.plainlink` as the generated runtime format.
- Skip rules that cannot be represented safely.
- Write an import manifest with upstream revision, input hash, output hash, and skip stats.
- Run `plainlink-rules verify-fixtures` with native rules and again with generated rules merged in.
- Document license and attribution requirements in [docs/RULE_SOURCES.md](docs/RULE_SOURCES.md).

## Code Contributions
Expand Down
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ PlainLink is early MVP software.
- Provides a native macOS menu bar app built with Apple Command Line Tools.
- Installs PlainLink to a stable user path with `plainlink install`.
- Installs PlainLink as a user LaunchAgent with `plainlink agent install`.
- Compiles conservative external rule-source subsets with `plainlink-rules`.
- Compiles conservative external rule-source subsets with reproducible manifests.
- Verifies native and imported rule behavior with `plainlink-rules verify-fixtures`.
- Validates community rule behavior with fixture-backed tests.
- Uses conservative rules that preserve unknown parameters by default.

Expand All @@ -43,6 +44,7 @@ cargo run -- restore
cargo run -- doctor
cargo run -- agent status
cargo run --bin plainlink-rules -- help
cargo run --bin plainlink-rules -- verify-fixtures
```

Expected output:
Expand Down Expand Up @@ -79,6 +81,23 @@ scripts/package-macos-app.sh

This creates `dist/packages/PlainLink-<version>-macos-<arch>.zip` and a `.sha256` checksum.

To compile a safe subset from an external source and write a manifest:

```sh
cargo run --bin plainlink-rules -- import-clearurls \
--input clearurls-data.minify.json \
--output rules/generated/clearurls.plainlink \
--manifest rules/generated/clearurls.manifest \
--source-revision <upstream-sha>
```

Before generated rules are considered for shipping, verify the native fixture corpus and then verify it again with the generated rules merged in:

```sh
cargo run --bin plainlink-rules -- verify-fixtures
cargo run --bin plainlink-rules -- verify-fixtures --rules rules/generated/clearurls.plainlink
```

## Project Layout

```text
Expand Down
11 changes: 9 additions & 2 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ flowchart TB
Sources["rules/sources.toml"]
Importers["plainlink-rules importers"]
Generated["generated .plainlink"]
Manifest["import manifest"]
Fixtures["tests/fixtures"]
Tests["Fixture-backed tests"]
Gate["plainlink-rules verify-fixtures"]
Tests["cargo test"]
end

Menu --> Install
Expand All @@ -44,9 +46,12 @@ flowchart TB
Doctor --> Agent
Sources --> Importers
Importers --> Generated
Importers --> Manifest
Generated --> Gate
Generated --> Match
Base --> Match
Fixtures --> Tests
Fixtures --> Gate
Gate --> Tests
Tests --> Core
```

Expand Down Expand Up @@ -84,6 +89,8 @@ sequenceDiagram
- LaunchAgent commands install and control the user-level watcher process.
- System-level clipboard cleaning is the product surface; browser extensions are not required for the core app.
- External rule importers run at build or contributor time and emit `.plainlink`; the runtime does not understand external list formats.
- Import manifests record upstream revision, input hash, output hash, and skip-reason counts.
- Generated rules must pass the fixture verifier before they are considered safe to ship.
- Community rule examples live as fixtures and run through `cargo test`.
- Root is not required; clipboard access belongs to the logged-in user session.
- The MVP uses `pbpaste` and `pbcopy` for a small macOS adapter.
Expand Down
13 changes: 11 additions & 2 deletions docs/RULES.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,16 @@ PlainLink keeps `.plainlink` as the runtime format, even when rules come from ex
```sh
cargo run --bin plainlink-rules -- import-clearurls \
--input clearurls-data.minify.json \
--output rules/generated/clearurls.plainlink
--output rules/generated/clearurls.plainlink \
--manifest rules/generated/clearurls.manifest \
--source-revision <upstream-sha>
```

Generated third-party rules should not be committed by default until source licensing and attribution have been reviewed. See [RULE_SOURCES.md](RULE_SOURCES.md).
Generated third-party rules should not be committed by default until source licensing and attribution have been reviewed. Before shipping generated rules, run the fixture corpus with native rules and again with generated rules merged in:

```sh
cargo run --bin plainlink-rules -- verify-fixtures
cargo run --bin plainlink-rules -- verify-fixtures --rules rules/generated/clearurls.plainlink
```

See [RULE_SOURCES.md](RULE_SOURCES.md).
42 changes: 41 additions & 1 deletion docs/RULE_SOURCES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ flowchart LR
Firefox["Firefox query stripping"] --> Compiler
Local["PlainLink additions"] --> Compiler
Compiler --> Generated["generated .plainlink"]
Compiler --> Manifest["import manifest"]
Generated --> Gate["verify-fixtures"]
Base["rules/base.plainlink"] --> Gate
Generated --> Runtime["PlainLink CLI / app"]
```

Expand All @@ -19,7 +22,9 @@ The first importer supports a conservative ClearURLs subset:
```sh
plainlink-rules import-clearurls \
--input clearurls-data.minify.json \
--output rules/generated/clearurls.plainlink
--output rules/generated/clearurls.plainlink \
--manifest rules/generated/clearurls.manifest \
--source-revision <upstream-sha>
```

It imports only providers that can be represented safely in `.plainlink`:
Expand All @@ -40,6 +45,41 @@ It skips:

That makes the importer incomplete by design, but safe. It is better to import fewer rules than to over-clean checkout, login, redirect, invite, or signed URLs.

## Safety Gate

Generated source rules need two checks before they can ship:

```sh
plainlink-rules verify-fixtures
plainlink-rules verify-fixtures --rules rules/generated/clearurls.plainlink
```

The first command proves native rules still satisfy the fixture corpus. The second command merges generated rules with native rules and fails on any fixture regression.

Each import can also write a deterministic manifest:

```text
source_name = ClearURLs Rules
source_url = https://rules2.clearurls.xyz/data.minify.json
source_revision = <upstream-sha>
input_sha256 = <sha256>
output_sha256 = <sha256>
providers_seen = 184
providers_imported = 121
providers_skipped = 63
rules_imported = 846
rules_skipped = 392

[skip_reasons]
exceptions = 12
wildcard_tld = 8
complete_provider = 2
unsupported_domain_regex = 31
unsupported_param_regex = 392
```

The manifest is for releases, CI logs, and review. It records exactly which upstream input produced the generated `.plainlink` output and why unsupported rules were rejected.

## Source Metadata

External source definitions live in:
Expand Down
Loading
Loading