From c02e544d91a36a5ed69b8170ae572cf011e7bb42 Mon Sep 17 00:00:00 2001 From: Erhan Acet Date: Wed, 4 Mar 2026 17:28:42 +0300 Subject: [PATCH 1/2] ENG-1760 Phase 1: rebuild source API surface --- bun.lock | 7 +++- packages/pq-key-encoder/ts/tsconfig.json | 1 + packages/pq-key-fingerprint/ts/package.json | 6 ++- packages/pq-key-fingerprint/ts/src/errors.ts | 40 ++++++++++++++++++++ packages/pq-key-fingerprint/ts/src/index.ts | 6 +-- packages/pq-key-fingerprint/ts/src/types.ts | 23 +++++++++++ packages/pq-key-fingerprint/ts/tsconfig.json | 1 + 7 files changed, 77 insertions(+), 7 deletions(-) create mode 100644 packages/pq-key-fingerprint/ts/src/errors.ts create mode 100644 packages/pq-key-fingerprint/ts/src/types.ts diff --git a/bun.lock b/bun.lock index 5231022..b033d57 100644 --- a/bun.lock +++ b/bun.lock @@ -143,7 +143,7 @@ }, "packages/pq-key-encoder/ts": { "name": "pq-key-encoder", - "version": "1.0.1", + "version": "1.0.3", "dependencies": { "pq-oid": "^1.0.1", }, @@ -154,6 +154,9 @@ "packages/pq-key-fingerprint/ts": { "name": "pq-key-fingerprint", "version": "0.0.1", + "dependencies": { + "pq-key-encoder": "^1.0.3", + }, "devDependencies": { "typescript": "^5.0.0", }, @@ -174,7 +177,7 @@ }, "packages/pq-oid/ts": { "name": "pq-oid", - "version": "1.0.1", + "version": "1.0.2", "devDependencies": { "typescript": "^5.0.0", }, diff --git a/packages/pq-key-encoder/ts/tsconfig.json b/packages/pq-key-encoder/ts/tsconfig.json index 8c52879..f19ea47 100644 --- a/packages/pq-key-encoder/ts/tsconfig.json +++ b/packages/pq-key-encoder/ts/tsconfig.json @@ -4,6 +4,7 @@ "module": "ESNext", "moduleResolution": "bundler", "declaration": true, + "composite": true, "outDir": "./dist", "rootDir": "./src", "strict": true, diff --git a/packages/pq-key-fingerprint/ts/package.json b/packages/pq-key-fingerprint/ts/package.json index b5aeb56..bdd3db3 100644 --- a/packages/pq-key-fingerprint/ts/package.json +++ b/packages/pq-key-fingerprint/ts/package.json @@ -9,7 +9,8 @@ "dist" ], "scripts": { - "build": "tsc", + "build": "tsc -b", + "test": "bun test", "prepublishOnly": "npm run build" }, "keywords": [ @@ -19,6 +20,9 @@ ], "author": "", "license": "MIT", + "dependencies": { + "pq-key-encoder": "^1.0.3" + }, "devDependencies": { "typescript": "^5.0.0" } diff --git a/packages/pq-key-fingerprint/ts/src/errors.ts b/packages/pq-key-fingerprint/ts/src/errors.ts new file mode 100644 index 0000000..4b52664 --- /dev/null +++ b/packages/pq-key-fingerprint/ts/src/errors.ts @@ -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'; + } +} diff --git a/packages/pq-key-fingerprint/ts/src/index.ts b/packages/pq-key-fingerprint/ts/src/index.ts index 3fdbd2e..9041fe8 100644 --- a/packages/pq-key-fingerprint/ts/src/index.ts +++ b/packages/pq-key-fingerprint/ts/src/index.ts @@ -1,4 +1,2 @@ -// pq-key-fingerprint - Generate fingerprints/hashes of PQ public keys -// Implementation coming soon - -export {}; +export * from './errors'; +export * from './types'; diff --git a/packages/pq-key-fingerprint/ts/src/types.ts b/packages/pq-key-fingerprint/ts/src/types.ts new file mode 100644 index 0000000..dade6b4 --- /dev/null +++ b/packages/pq-key-fingerprint/ts/src/types.ts @@ -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 & { + alg: EncoderAlgorithmName; + type: 'public'; +}; + +export type PublicKeyInput = PublicKeyData | { alg: EncoderAlgorithmName; bytes: Uint8Array }; + +export type FingerprintInput = PublicKeyInput | Uint8Array | string | PQJwk; + +export type FingerprintResult = string | Uint8Array; diff --git a/packages/pq-key-fingerprint/ts/tsconfig.json b/packages/pq-key-fingerprint/ts/tsconfig.json index 0e1d7ae..78cc000 100644 --- a/packages/pq-key-fingerprint/ts/tsconfig.json +++ b/packages/pq-key-fingerprint/ts/tsconfig.json @@ -10,5 +10,6 @@ "esModuleInterop": true, "skipLibCheck": true }, + "references": [{ "path": "../../pq-key-encoder/ts" }], "include": ["src"] } From 5ece802d95d861b91f6d580e120e1b008b6a19ca Mon Sep 17 00:00:00 2001 From: Erhan Acet Date: Wed, 4 Mar 2026 17:53:46 +0300 Subject: [PATCH 2/2] Skills updated --- .claude/skills/create-plan-linear/SKILL.md | 12 +++--- .claude/skills/implement-plan-linear/SKILL.md | 40 ++++++++++++++----- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/.claude/skills/create-plan-linear/SKILL.md b/.claude/skills/create-plan-linear/SKILL.md index 8da1925..2e748f3 100644 --- a/.claude/skills/create-plan-linear/SKILL.md +++ b/.claude/skills/create-plan-linear/SKILL.md @@ -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]" --- @@ -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. @@ -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`). @@ -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 @@ -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 diff --git a/.claude/skills/implement-plan-linear/SKILL.md b/.claude/skills/implement-plan-linear/SKILL.md index 38c24ab..0c8350b 100644 --- a/.claude/skills/implement-plan-linear/SKILL.md +++ b/.claude/skills/implement-plan-linear/SKILL.md @@ -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 "" ` - - 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 "(/): phase - ()" ` + - `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: + - ``: 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 folder name under `packages/` (e.g. `pq-jws`, `pq-oid`, `pq-key-encoder`) + - ``: language folder under the package (`ts`, `rust`, or `python`) + - ``: phase number from the plan + - ``: concise summary of the phase scope + - ``: Linear issue key provided at invocation (e.g. `ENG-1640`) + - Determine `` 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 --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: `(/): phase - ()` — 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 @@ -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. \ No newline at end of file