Skip to content

Commit 2ddb3d2

Browse files
Phase 11 features: covenant-apply, machine-readable, plugin, metals, custom DB
All remaining Phase 11 deliverables + nice-to-have features in one commit. 274/274 tests passing on Scala Native. === enforce: covenant-apply subcommand === New `re-scale enforce covenant-apply` stamps or updates a Covenant header in a Scala file's leading block comment. Extracts current method set + LOC, optionally verifies zero shortcut hits (--force to skip), writes/updates the Covenant block before `*/`. Round-trip verified: Covenant.parse and Covenant.verify both work on created headers. 7 tests. CLI: re-scale enforce covenant-apply \ --file <path> --source <ref> \ [--spec-pass N] [--covenant full-port] [--dry-run] [--force] === enforce: --machine-readable output === `--machine-readable` flag for `enforce shortcuts`, `stale-stubs`, and `verify --all` — outputs TSV (tab-separated with `#`-prefixed header) to stdout for CI diff scripts and baseline comparison. Machine-readable mode suppresses informational stderr messages. === re-scale metals === Metals LSP server lifecycle commands (install/start/stop/status). Ported from sge-dev MetalsCmd (~100 LOC). Uses a PID file under .rescale/.metals-pid and Coursier for install. Wired into Main.scala. === Custom DB tables via .rescale/databases.yaml === Projects can define arbitrary TSV-backed tables with column schemas, key columns, and defaults. `re-scale db <table> list/get/set/add/ delete/stats` works on any declared table. Motivating use case: ssg-sass port-tasks tracking without hardcoding into the binary. Engine creates the TSV file on first write with correct headers. === Hook rules: adb deny + .rescale/data guard === - adb/fastboot deny rule in DefaultRules — denies Android Debug Bridge commands by default; projects opt in via claude-hooks.yaml. - .rescale/data/ access guard — Read/Edit/Write tool calls on paths containing .rescale/data/ are denied, forcing agents to use `re-scale db` commands for data integrity (atomic writes, file locking, consistent TSV formatting). 5 new tests. === CI baseline diff script === `scripts/baseline-diff.sh` — runs enforce shortcuts --machine-readable, diffs against a stored baseline TSV in .rescale/data/, exits 1 on new regressions (one-directional: improvements don't fail). === Plugin packaging: .claude-plugin/ with 13 seed skills === Ships re-scale as a Claude Code plugin. Skills auto-load when context matches their description — no manual invocation needed. Guide skills (generic porting knowledge): guide-conversion Cross-language conversion rules guide-code-style Formatting + Scala 3 conventions guide-nullable Nullable[A] opaque type patterns guide-control-flow boundary/break patterns guide-verification Post-conversion verification checklist Workflow skills (re-scale command orchestration): rescale-audit-file Full file audit against source rescale-verify-file Convention + compile + test verification rescale-find-issues Quality scan (shortcuts + stale-stubs + grep) rescale-check-progress Migration/audit/covenant progress dashboard rescale-audit-status Audit status per-package or overall rescale-gap-fix Fix enforcement failures using template All skills use the proper format: description-only frontmatter, $ARGUMENTS for parameterized skills, no name: field. === Documentation === - docs/contributing/verification-checklist.md — rewritten against re-scale enforce commands (7-step checklist with quick-reference) - docs/contributing/gap-fix-task-template.md — standard template for driving gap-fix waves (task prompt + batch workflow + triage table) - README.md — expanded Install section with prerequisites, new "Claude Code skills (per project)" subsection with 13-skill table, updated test counts from 245 → 274, added metals/ to architecture === Infrastructure === - Tsv.readOrEmpty helper for tables that may not exist yet - extractStringField helper in HookCmd for non-Bash tool inspection
1 parent 10a7d05 commit 2ddb3d2

28 files changed

Lines changed: 1634 additions & 48 deletions

File tree

.claude-plugin/plugin.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "re-scale",
3+
"description": "Scala Native porting toolkit — enforcement gates, migration tracking, and conversion guides",
4+
"version": "0.1.0",
5+
"author": {"name": "kubuszok"}
6+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
description: Code style rules for Scala 3 porting projects — headers, formatting, conventions
3+
---
4+
5+
# Code style
6+
7+
- **License header**: Apache-2.0, with Migration notes block for audited files
8+
- **Braces required** (`-no-indent`): `{}` for all trait/class/enum/method defs
9+
- **Split packages**: `package ssg` / `package md` / `package core` (never flat)
10+
- **No `return`**: use `boundary`/`break`
11+
- **No `null`**: use `Nullable[A]`
12+
- **No `scala.Enumeration`**: use Scala 3 `enum`, preferably `extends java.lang.Enum`
13+
- **Case classes must be `final`**
14+
- **No Java-style getters/setters**: no-logic `getX()`/`setX(v)` → public `var x`
15+
- **Preserve all original comments** from the source
16+
- **Fix bugs, don't work around them**: when a test reveals a pre-existing bug, fix it
17+
18+
## Formatting
19+
20+
Scalafmt config is `.scalafmt.conf` at project root. Run:
21+
```
22+
re-scale build fmt
23+
```
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
description: boundary/break patterns replacing return/break/continue in Scala 3
3+
---
4+
5+
# Control flow guide
6+
7+
Scala 3 with `-no-indent` and the project's `no return` rule requires
8+
`scala.util.boundary` / `break` for early exit patterns.
9+
10+
## Replacing return
11+
12+
```scala
13+
import scala.util.boundary, boundary.break
14+
15+
def find(xs: List[Int]): Int = boundary {
16+
for (x <- xs) {
17+
if (x > 10) break(x)
18+
}
19+
-1 // default
20+
}
21+
```
22+
23+
## Replacing break/continue in loops
24+
25+
```scala
26+
boundary {
27+
for (x <- xs) {
28+
if (shouldSkip(x)) break() // acts like continue in the innermost boundary
29+
process(x)
30+
}
31+
}
32+
```
33+
34+
## Nested boundaries
35+
36+
Use `boundary.Label` to disambiguate:
37+
```scala
38+
boundary[Int] { outer ?=>
39+
for (xs <- xss) {
40+
boundary[Unit] { inner ?=>
41+
for (x <- xs) {
42+
if (done(x)) break(x)(using outer)
43+
if (skip(x)) break(())(using inner)
44+
}
45+
}
46+
}
47+
-1
48+
}
49+
```
50+
51+
The shortcuts scanner flags `var done/continue/stop` as `flag-break-var`.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
description: Cross-language conversion rules for porting Java/Dart/Ruby to Scala 3
3+
---
4+
5+
# Conversion guide
6+
7+
Load the appropriate language-specific rules based on the source language:
8+
9+
- **Java → Scala 3** (flexmark-java, liqp): Java getters → Scala vals/defs,
10+
checked exceptions → Either/Try, generics → type parameters, streams → FS2
11+
- **Dart → Scala 3** (dart-sass): Dart null-safety → Nullable[A], extension
12+
methods → extension objects, cascade notation → builder pattern
13+
- **Ruby → Scala 3** (jekyll-minifier): dynamic typing → ADT/sealed trait,
14+
monkey-patching → implicit class, blocks → lambdas
15+
16+
## Key principles
17+
18+
1. Port the LOGIC, not the syntax. Idiomatic Scala 3 over transliteration.
19+
2. Use `Nullable[A]` for nullable values — never raw `null` except at Java interop.
20+
3. Use `boundary`/`break` instead of `return`/`break`/`continue`.
21+
4. All `case class` must be `final`.
22+
5. No `scala.Enumeration` — use Scala 3 `enum`.
23+
6. Preserve all original comments.
24+
7. Fix bugs from the original when found during porting.
25+
26+
## Verification
27+
28+
After converting, run:
29+
```
30+
re-scale enforce shortcuts --file <path> # must be 0 hits
31+
re-scale enforce compare --port <scala> --source <original> --strict
32+
re-scale build compile --module <mod> --all
33+
re-scale test unit --module <mod>
34+
```
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
description: Nullable[A] opaque type patterns for null-safe Scala porting
3+
---
4+
5+
# Nullable guide
6+
7+
Use `Nullable[A]` instead of raw `null`. The opaque type provides:
8+
- `Nullable.empty[A]` instead of `null`
9+
- `Nullable(value)` to wrap
10+
- `.getOrElse(default)` for safe unwrapping
11+
- `.map(f)` / `.flatMap(f)` for chaining
12+
- `.orNull` only at Java interop boundaries (requires `@nowarn` + comment)
13+
14+
## Common patterns
15+
16+
```scala
17+
// Java: String result = map.get(key); // nullable
18+
// Scala:
19+
val result: Nullable[String] = Nullable(map.get(key))
20+
result.getOrElse("default")
21+
22+
// Java: if (x != null) x.doSomething()
23+
// Scala:
24+
x.foreach(_.doSomething())
25+
```
26+
27+
Never use `null.asInstanceOf[T]` — the shortcuts scanner flags it as `null-cast`.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
description: Post-conversion verification checklist using re-scale enforce
3+
---
4+
5+
# Verification checklist
6+
7+
Run these checks after every conversion, in order (cheapest first):
8+
9+
1. **Compile**: `re-scale build compile --module <M> --all`
10+
2. **Tests**: `re-scale test unit --module <M> --all`
11+
3. **Shortcuts**: `re-scale enforce shortcuts --file <path>` → 0 hits
12+
4. **Compare**: `re-scale enforce compare --port <scala> --source <original> --strict`
13+
5. **Stale stubs**: `re-scale enforce stale-stubs --src <dir>`
14+
6. **Covenant verify**: `re-scale enforce verify --file <path>`
15+
7. **Stamp**: `re-scale enforce covenant-apply --file <path> --source <ref> [--spec-pass N]`
16+
17+
See `docs/contributing/verification-checklist.md` for full details.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
description: Audit a ported Scala file against its original source — runs shortcuts, compare, stale-stubs, and records the result
3+
---
4+
5+
Audit the file at `$ARGUMENTS` against its original source.
6+
7+
## Procedure
8+
9+
1. Read the Scala file with the Read tool.
10+
11+
2. Identify the original source file:
12+
- Check the license header for `Covenant-source-reference:` or a `Migration notes:` block
13+
- Or look in the `original-src/` submodule using the project's type-mapping convention
14+
15+
3. Read the original source file from the local submodule (**never fetch from GitHub**).
16+
17+
4. Run enforcement checks:
18+
```
19+
re-scale enforce shortcuts --file <path>
20+
re-scale enforce compare --port <path> --source <original> --strict
21+
re-scale enforce verify --file <path>
22+
```
23+
24+
5. Check conventions:
25+
- License header with original source attribution
26+
- No `return`, no raw `null` (use `Nullable[A]`)
27+
- `final case class`, split packages, braces required
28+
- Uses `boundary`/`break` where the original has early returns
29+
30+
6. Check tests — does the original have tests? Are they ported?
31+
32+
7. Record the audit result:
33+
```
34+
re-scale db audit set <file_path> --status <pass|minor_issues|major_issues> --tested <yes|no|partial> --notes "..."
35+
```
36+
37+
8. If the file passes all checks, stamp the covenant:
38+
```
39+
re-scale enforce covenant-apply --file <path> --source <original> [--spec-pass N]
40+
```
41+
42+
## Important
43+
44+
**Do NOT access .rescale/data/ files directly.** Use `re-scale db` commands.
45+
**Do NOT use shell commands for search/read.** Use Grep, Glob, Read, Edit tools.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
description: Show audit status for a package or the whole project — counts by status, identifies unaudited files
3+
---
4+
5+
Show audit status. If `$ARGUMENTS` is provided, show status for that package; otherwise show overall stats.
6+
7+
## Procedure
8+
9+
### Overall (no arguments)
10+
11+
1. Query audit database:
12+
```
13+
re-scale db audit stats
14+
```
15+
16+
2. Show breakdown by status (pass / minor_issues / major_issues).
17+
18+
### Per-package (with arguments)
19+
20+
1. Query audit database for the package:
21+
```
22+
re-scale db audit list --package $ARGUMENTS
23+
```
24+
25+
2. Show each file's status, identify unaudited files in the package.
26+
27+
## Important
28+
29+
**Do NOT access .rescale/data/ files directly.** Use `re-scale db audit` commands.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
description: Show migration and audit progress — database stats, covenant coverage, enforcement summary
3+
---
4+
5+
Show migration progress for this project.
6+
7+
## Procedure
8+
9+
1. Query migration database:
10+
```
11+
re-scale db migration stats
12+
```
13+
14+
2. Query audit database:
15+
```
16+
re-scale db audit stats
17+
```
18+
19+
3. Run a covenant coverage check:
20+
```
21+
re-scale enforce verify --all --machine-readable
22+
```
23+
Count pass vs fail (excluding "no covenant header" which just means not yet stamped).
24+
25+
4. Run a shortcuts summary:
26+
```
27+
re-scale enforce shortcuts --machine-readable
28+
```
29+
Count total hits and files affected.
30+
31+
5. Report:
32+
- Migration: X files converted out of Y total
33+
- Audit: X pass, Y minor, Z major
34+
- Covenanted: N files with covenant headers, M verified passing
35+
- Shortcuts: N files still have hits (gap-fix candidates)
36+
37+
## Important
38+
39+
**Do NOT access .rescale/data/ files directly.** Use `re-scale db` commands.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
description: Find code quality issues across the codebase — shortcuts, stale stubs, open issues, convention violations
3+
---
4+
5+
Find code quality issues in the project.
6+
7+
## Procedure
8+
9+
1. Run enforcement scans:
10+
```
11+
re-scale enforce shortcuts
12+
re-scale enforce stale-stubs
13+
```
14+
15+
2. Search for convention violations using the Grep tool:
16+
- `\breturn\b` in `*/src/main/scala/` — remaining `return` statements
17+
- `\bnull\b` in `*/src/main/scala/` — raw null usage
18+
- `TODO|FIXME` in `*/src/main/scala/` — outstanding work markers
19+
20+
3. Check issues database:
21+
```
22+
re-scale db issues list --status open
23+
```
24+
25+
4. Summarize findings by severity and suggest fixes.
26+
27+
## Important
28+
29+
**Do NOT access .rescale/data/ files directly.** Use `re-scale db` commands.
30+
**Do NOT use shell commands for search.** Use the Grep tool.

0 commit comments

Comments
 (0)