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
12 changes: 7 additions & 5 deletions .claude/skills/create-plan-linear/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: create-plan-linear
description: "Create detailed implementation plans with codebase research and, after explicit user approval, publish the approved phased plan to Linear by creating a project under a chosen initiative plus phase and subphase issues assigned to Timur Guvenkaya."
description: "Create detailed implementation plans with codebase research and, after explicit user approval, publish the approved phased plan to Linear by creating a project under a chosen initiative plus phase and subphase issues assigned to a user chosen at runtime."
argument-hint: "[ticket-or-file-path]"
---

Expand All @@ -11,7 +11,7 @@ Create a detailed implementation plan first. Only after explicit user approval,
## Intake

- Read any provided ticket, plan, or file paths fully before planning.
- If key inputs are missing, ask for them: objective, constraints, references, and preferred project name.
- If key inputs are missing, ask for them: objective, constraints, references, preferred project name, target assignee, and plan file path.
- Capture initiative and team context early when available.
- Ask only questions that cannot be answered from the codebase or provided context.

Expand Down Expand Up @@ -128,8 +128,9 @@ Create a detailed implementation plan first. Only after explicit user approval,
- Set `summary` to a concise one-line overview from the plan.

4. Resolve assignee
- Resolve Timur via `mcp__linear__get_user` with query `timur guvenkaya`.
- If no exact match is found, ask the user before assigning to another user.
- Ask the user which assignee to use if not already provided.
- Resolve the provided assignee via `mcp__linear__get_user`.
- If no exact match is found, ask the user to confirm the intended user before creating issues.

5. Prepare labels and severity
- Derive labels from phase scope (for example: `consensus`, `execution`, `networking`, `docs`, `testing`).
Expand All @@ -148,7 +149,7 @@ Create a detailed implementation plan first. Only after explicit user approval,
- Create one Linear issue per top-level phase under the created project.
- Set issue title to the phase title.
- Set issue description to the phase plan content (scope, changes, and success criteria).
- Assign each issue to Timur.
- Assign each issue to the resolved assignee.
- Add derived labels, severity label, and priority.

7. Create subphase sub-issues
Expand All @@ -160,6 +161,7 @@ Create a detailed implementation plan first. Only after explicit user approval,
8. Return sync summary
- Report created project identifier/name.
- Report each created phase issue and sub-issue with identifiers.
- Report the plan file path used for sync.
- Call out any assumptions made (team inference, severity defaults, inferred labels).

## Execution Rules
Expand Down
40 changes: 30 additions & 10 deletions .claude/skills/implement-plan-linear/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,30 +93,50 @@ Please run the manual verification steps for this phase and confirm when complet

## Graphite Workflow

After manual confirmation for a phase, run these three steps in order:
Phases form a **Graphite stack** — each phase branch stacks on top of the previous one. The stack is created incrementally: phase 1 branches off trunk, phase 2 branches off phase 1, and so on. The entire stack is merged together after all phases are complete and reviewed.

1. **Sync trunk and clean up merged branches:**
- `gt sync` — pulls latest trunk, restacks open branches, prompts to delete merged branches (accept deletions when prompted).
After manual confirmation for a phase, run these steps in order:

1. **Sync trunk and restack:**
- `gt sync` — pulls latest trunk, restacks open branches, accepts deletion of merged branches. Safe to run whether on trunk or on an existing stack branch.

2. **Create the branch with all changes committed:**
- Fetch the branch name from the Linear issue via `mcp__linear__get_issue` (the `gitBranchName` field).
- `gt create -am "<phase commit message>" <linear-branch-name>`
- This stages all changes, commits them, and creates a new Graphite branch in one step. The branch name MUST be the one from the Linear issue (e.g. `feature/eng-1242`).
- `gt create -am "<type>(<package>/<language>): phase <N> - <description> (<issue-key>)" <linear-branch-name>`
- `gt create` stacks on whatever branch you are currently on — trunk for phase 1, the previous phase's branch for phase 2+.
- Commit message format:
- `<type>`: conventional commit type derived from the phase's intent:
- `feat` — new functionality, new API surface, new exports
- `fix` — bug fixes, correcting broken behavior
- `refactor` — restructuring without behavior change
- `test` — adding/updating tests only
- `docs` — documentation, README, comments only
- `chore` — build config, CI, package metadata, tooling
- `<package>`: package folder name under `packages/` (e.g. `pq-jws`, `pq-oid`, `pq-key-encoder`)
- `<language>`: language folder under the package (`ts`, `rust`, or `python`)
- `<N>`: phase number from the plan
- `<description>`: concise summary of the phase scope
- `<issue-key>`: Linear issue key provided at invocation (e.g. `ENG-1640`)
- Determine `<type>` by reading the phase title and scope from the plan — pick the type that best describes the primary intent of the phase.
- Examples:
- `feat(pq-jws/ts): phase 1 - define public contracts (ENG-1640)`
- `test(pq-jws/ts): phase 4 - comprehensive test suite (ENG-1643)`
- `fix(pq-oid/rust): phase 2 - correct DER length encoding (ENG-1500)`

3. **Submit and publish the stack:**
- `gt submit --publish`
- `gt submit --publish` — pushes all branches in the stack and creates/updates PRs for each.

4. **Trigger automated review:**
- After the PR is created/updated, post a review trigger comment:
- `gh pr comment <PR-number> --body "@codex review"`

Rules:

- Always run `gt sync` first to avoid "already merged" errors blocking submit.
- Always run `gt sync` before `gt create` — it is safe on stack branches and keeps the stack rebased on latest trunk.
- The branch name comes from Linear's `gitBranchName` field — never invent branch names.
- `gt create -am` handles staging, committing, and branch creation — do not use `git add` or `git commit` separately.
- Use commit messages tied to phase scope, not generic text.
- Commit message must follow: `<type>(<package>/<language>): phase <N> - <description> (<issue-key>)` — derive type from the phase intent, package/language from the plan path, phase number from the plan, and issue key from the input.
- Do not run `gt submit --publish` before manual confirmation.
- Do **not** merge individual phase PRs — the entire stack is merged together after all phases are complete.
- If a `gt` command fails, report the exact command and error output.

## When to Use Sub-agents
Expand Down Expand Up @@ -150,4 +170,4 @@ For each completed phase, report:
- Re-read relevant plan and code before assuming root cause.
- Consider whether the codebase evolved since the plan was written.
- Surface blockers with exact command errors or plan/code mismatches.
- Ask one focused question to unblock.
- Ask one focused question to unblock.
7 changes: 5 additions & 2 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/pq-key-encoder/ts/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"module": "ESNext",
"moduleResolution": "bundler",
"declaration": true,
"composite": true,
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
Expand Down
6 changes: 5 additions & 1 deletion packages/pq-key-fingerprint/ts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"dist"
],
"scripts": {
"build": "tsc",
"build": "tsc -b",
"test": "bun test",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the 'test': 'bun test' script since no test files exist yet. The bun test runner fails when it cannot find any files with test naming conventions (.test, test, .spec, spec). This script should be added back when actual test files are implemented.

Spotted by Graphite (based on CI logs)

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

"prepublishOnly": "npm run build"
},
"keywords": [
Expand All @@ -19,6 +20,9 @@
],
"author": "",
"license": "MIT",
"dependencies": {
"pq-key-encoder": "^1.0.3"
},
"devDependencies": {
"typescript": "^5.0.0"
}
Expand Down
40 changes: 40 additions & 0 deletions packages/pq-key-fingerprint/ts/src/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/** Base error for pq-key-fingerprint failures. */
export class FingerprintError extends Error {
constructor(message: string) {
super(message);
this.name = 'FingerprintError';
Object.setPrototypeOf(this, new.target.prototype);
}
}

/** Error for invalid or missing fingerprint input values. */
export class InvalidFingerprintInputError extends FingerprintError {
constructor(message: string) {
super(message);
this.name = 'InvalidFingerprintInputError';
}
}

/** Error for key-type mismatches, such as passing private keys. */
export class InvalidKeyTypeError extends FingerprintError {
constructor(message: string) {
super(message);
this.name = 'InvalidKeyTypeError';
}
}

/** Error for unsupported digest algorithm selections. */
export class UnsupportedDigestError extends FingerprintError {
constructor(message: string) {
super(message);
this.name = 'UnsupportedDigestError';
}
}

/** Error for missing runtime cryptographic capabilities. */
export class RuntimeCapabilityError extends FingerprintError {
constructor(message: string) {
super(message);
this.name = 'RuntimeCapabilityError';
}
}
6 changes: 2 additions & 4 deletions packages/pq-key-fingerprint/ts/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
// pq-key-fingerprint - Generate fingerprints/hashes of PQ public keys
// Implementation coming soon

export {};
export * from './errors';
export * from './types';
23 changes: 23 additions & 0 deletions packages/pq-key-fingerprint/ts/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { AlgorithmName as EncoderAlgorithmName, KeyData, PQJwk } from 'pq-key-encoder';

export type { AlgorithmName } from 'pq-key-encoder';

export type FingerprintDigest = 'SHA-256' | 'SHA-384' | 'SHA-512';

export type FingerprintEncoding = 'hex' | 'base64' | 'base64url' | 'bytes';

export interface FingerprintOptions {
digest?: FingerprintDigest;
encoding?: FingerprintEncoding;
}

export type PublicKeyData = Omit<KeyData, 'type' | 'alg'> & {
alg: EncoderAlgorithmName;
type: 'public';
};

export type PublicKeyInput = PublicKeyData | { alg: EncoderAlgorithmName; bytes: Uint8Array };

export type FingerprintInput = PublicKeyInput | Uint8Array | string | PQJwk;

export type FingerprintResult = string | Uint8Array;
1 change: 1 addition & 0 deletions packages/pq-key-fingerprint/ts/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
"esModuleInterop": true,
"skipLibCheck": true
},
"references": [{ "path": "../../pq-key-encoder/ts" }],
"include": ["src"]
}
Loading