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
102 changes: 102 additions & 0 deletions dev-team/commands/dev-license.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
name: ring:dev-license
description: Apply or switch the license for the current repository
argument-hint: "[apache|elv2|proprietary] [options]"
---

Apply or switch the license for the current repository.

## Usage

```
/ring:dev-license [license-type] [options]
```

## Arguments

| Argument | Required | Description |
|----------|----------|-------------|
| `license-type` | No* | One of: `apache`, `elv2`, `proprietary` |

*If omitted, the skill will detect the current license and ask which to apply.

## Options

| Option | Description | Example |
|--------|-------------|---------|
| `--dry-run` | Show what would change without modifying files | `--dry-run` |
| `--year YEAR` | Override copyright year (default: current year) | `--year 2025` |
| `--holder NAME` | Override copyright holder (default: Lerian Studio Ltd.) | `--holder "Lerian Studio Ltd."` |

## License Types

| Type | Full Name | SPDX | Use Case |
|------|-----------|------|----------|
| `apache` | Apache License 2.0 | `Apache-2.0` | Open source (e.g., Midaz core) |
| `elv2` | Elastic License v2 | `Elastic-2.0` | Source-available Lerian products |
| `proprietary` | Lerian Studio General License | `LicenseRef-Lerian-Proprietary` | Internal/closed repos |

## Examples

```bash
# Apply Apache 2.0 license
/ring:dev-license apache

# Switch to ELv2
/ring:dev-license elv2

# Apply proprietary license with specific year
/ring:dev-license proprietary --year 2024

# Check what would change without modifying
/ring:dev-license apache --dry-run

# Detect current license (interactive)
/ring:dev-license
```

## What It Does

1. **Detects** current license (LICENSE file, source headers, SPDX identifiers)
2. **Confirms** change with user (if switching from an existing license)
3. **Writes** the LICENSE file with the full license text
4. **Updates** all source file headers (.go, .ts, .js) to match
5. **Updates** SPDX identifiers in go.mod/package.json (if present)
6. **Updates** README.md license badge/section (if present)
7. **Validates** all files have consistent headers

## Related Commands

| Command | Description |
|---------|-------------|
| `/ring:dev-cycle` | Development cycle (includes license check at Gate 0) |
| `/ring:dev-refactor` | Codebase analysis (may detect license inconsistencies) |

---

## MANDATORY: Load Full Skill

**This command MUST load the skill for complete workflow execution.**

```
Use Skill tool: ring:dev-licensing
```

The skill contains the complete 4-gate workflow with:
- License detection and identification
- User confirmation gate
- Agent dispatch for header updates
- Validation with consistency checks
- Anti-rationalization tables
- Pressure resistance scenarios

## Execution Context

Pass the following context to the skill:

| Parameter | Value |
|-----------|-------|
| `license_type` | First argument: `apache`, `elv2`, or `proprietary` (if provided) |
| `dry_run` | `true` if `--dry-run` flag present |
| `copyright_year` | Value of `--year` option (default: current year) |
| `copyright_holder` | Value of `--holder` option (default: `Lerian Studio Ltd.`) |
83 changes: 64 additions & 19 deletions dev-team/docs/standards/golang/core.md
Original file line number Diff line number Diff line change
Expand Up @@ -844,23 +844,64 @@ grep -rn "CREATE TABLE\|ALTER TABLE\|DROP TABLE" --include="*.go" ./internal
| Compliance audit failures | Audit-ready codebase |
| Inconsistent attribution | Uniform legal protection |

### Required Format (Elastic License 2.0)
### Important: License Is Per-Repository

Lerian uses three license types, chosen per-app. The actual header text MUST match the LICENSE file in the repository root. Use the `/ring:dev-license` command (or the `ring:dev-licensing` skill) to apply or switch licenses consistently across a repository.

| License | SPDX Identifier | When Used |
| ------- | --------------- | --------- |
| Apache 2.0 | `Apache-2.0` | Open source projects (e.g., Midaz core) |
| Elastic License v2 | `Elastic-2.0` | Source-available Lerian products |
| Proprietary | `LicenseRef-Lerian-Proprietary` | Internal/closed repositories |

### Required Format: Apache 2.0

```go
// Copyright (c) 2025 Lerian Studio Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package yourpackage
```

### Required Format: Elastic License 2.0

```go
// Copyright (c) 2025 Lerian Studio Ltd.
// Use of this source code is governed by the Elastic License 2.0
// that can be found in the LICENSE file.

package yourpackage
```

### Required Format: Proprietary (Lerian Studio General License)

```go
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License 2.0;
// you may not use this file except in compliance with the Elastic License 2.0.
// Copyright (c) 2025 Lerian Studio Ltd. All rights reserved.
// This source code is proprietary and confidential.
// Unauthorized copying of this file is strictly prohibited.

package yourpackage
```

### Header Components

| Component | Value | Notes |
| ----------------- | --------------------- | ----------------------------------------- |
| Copyright holder | `Elasticsearch B.V.` | Fixed for all projects |
| License reference | `Elastic License 2.0` | Or as specified in LICENSE file |
| LICENSE location | Inline in header | No separate LICENSE file reference needed |
| Component | Value | Notes |
| ----------------- | ------------------------------ | -------------------------------------------------- |
| Copyright holder | `Lerian Studio Ltd.` | Default for all Lerian projects |
| Copyright year | Current year (e.g., `2025`) | Update when making significant changes |
| License reference | Depends on repository LICENSE | MUST match the LICENSE file in the repo root |
| LICENSE location | Reference to LICENSE file | Header points to LICENSE file in repo root (e.g., "that can be found in the LICENSE file") |

Comment thread
coderabbitai[bot] marked this conversation as resolved.
### Files That MUST Have Headers

Expand All @@ -883,9 +924,9 @@ package yourpackage
### Correct Examples

```go
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License 2.0;
// you may not use this file except in compliance with the Elastic License 2.0.
// Copyright (c) 2025 Lerian Studio Ltd.
// Use of this source code is governed by the Elastic License 2.0
// that can be found in the LICENSE file.

package bootstrap

Expand All @@ -896,9 +937,9 @@ import (
```

```go
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License 2.0;
// you may not use this file except in compliance with the Elastic License 2.0.
// Copyright (c) 2025 Lerian Studio Ltd.
// Use of this source code is governed by the Elastic License 2.0
// that can be found in the LICENSE file.

package bootstrap_test

Expand All @@ -916,18 +957,22 @@ package model
import "time"

// ❌ FORBIDDEN: Wrong format (missing full license text)
// Copyright Elasticsearch B.V.
// Copyright Lerian Studio
// Licensed under Elastic License 2.0
package model

// ❌ FORBIDDEN: Header after package declaration
package model

// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License 2.0;
// you may not use this file except in compliance with the Elastic License 2.0.
// Copyright (c) 2025 Lerian Studio Ltd.
// Use of this source code is governed by the Elastic License 2.0
// that can be found in the LICENSE file.

import "time"

// ❌ FORBIDDEN: Header from a different license than the repo LICENSE file
// (e.g., Apache header in an ELv2 repo, or ELv2 header in an Apache repo)
// Headers MUST match the LICENSE file in the repository root
```

### Verification Commands
Expand Down
22 changes: 22 additions & 0 deletions dev-team/skills/dev-cycle/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -1834,6 +1834,28 @@ PM team task files often omit external_dependencies. If the codebase uses postgr
Multi-tenant state is detected here and passed to Gate 0 (implementation) and Gate 0.5G (verification). See [multi-tenant.md](../../docs/standards/golang/multi-tenant.md) for the canonical model and compliance criteria.
</auto_detect_reason>

### License Detection (Advisory)

Detect the repository license at cycle start. This check is advisory — it does not block Gate 0. If no license is found, prompt the user; if the user declines, log a warning and proceed.

```text
7. Detect repository license:
license_type = "unknown"

- ls LICENSE LICENSE.md LICENSE.txt 2>/dev/null
- If found:
- grep -l "Apache License" LICENSE* → license_type = "apache"
- grep -l "Elastic License" LICENSE* → license_type = "elv2"
- grep -l "All rights reserved.*Lerian" LICENSE* → license_type = "proprietary"
- If not found (no LICENSE file):
→ Ask user: "No LICENSE file detected. Which license should this repository use? [apache|elv2|proprietary|skip]"
→ If user selects a license: set license_type = <chosen value>, invoke Skill("ring:dev-licensing") with chosen type
→ If user selects "skip": set license_type = "skip", log "⚠️ WARNING: No LICENSE file. License headers may be inconsistent."

Store: state.license_type = license_type
Log: "License detected: {license_type}"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
```

---

## Step 2: Gate 0 - Implementation (Per Execution Unit)
Expand Down
Loading