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
5 changes: 5 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"enabledPlugins": {
"superpowers@claude-plugins-official": true
}
Comment on lines +1 to +4
}
49 changes: 0 additions & 49 deletions AGENTS.md

This file was deleted.

16 changes: 16 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,19 @@ Blog posts are `.mdx` files in `content/`. The `src/data/blog.ts` utility handle
### Path Alias

`@/*` maps to `src/*` — use this for all internal imports.

## Git Workflow & Releases

Branch model: feature branches → `devel` → `main`. Both `devel` and `main` are protected by a repository ruleset (no direct pushes, no force-pushes, no branch deletion, PRs required).

Versioning is fully automated by `semantic-release` (config in `release.config.js`, workflow in `.github/workflows/release.yml`), which only runs on pushes to `main` and reads commit messages via `@semantic-release/commit-analyzer` (Angular preset) to decide the version bump.

**This means every PR into `devel` or `main` must be merged with "Squash and merge", never "Rebase and merge" or "Create a merge commit".** Rebase/merge-commit strategies leave multiple non-squashed commits (or, in the case of GitHub's rebase-and-merge, commits whose signature gets silently dropped on replay) in the history instead of one clean, conventional-commit-formatted entry — this has already caused a signature-verification incident on `devel` that had to be fixed by rewriting history.

The PR title becomes the squash commit message and must follow [Conventional Commits](https://www.conventionalcommits.org/):
- `feat: ...` → minor bump
- `fix: ...` → patch bump
- `feat!: ...` or a `BREAKING CHANGE:` footer → major bump
- `chore:`, `docs:`, `refactor:`, etc. → no release

`.github/workflows/ci.yml` (lint + build) runs on every PR targeting `main` or `devel`.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ My personal portfolio website built with Next.js, showcasing my work experience,
- [Tech Stack](#tech-stack)
- [Getting Started](#getting-started)
- [Commands](#commands)
- [Contributing](#contributing)
- [License](#license)

## Tech Stack
Expand Down Expand Up @@ -50,6 +51,22 @@ The development server starts at `http://localhost:3000`.
| `npm run start` | Start production server |
| `npm run lint` | Run ESLint |

## Contributing

This repo uses [Conventional Commits](https://www.conventionalcommits.org/) and [semantic-release](https://semantic-release.gitbook.io/) to automate versioning and GitHub releases from `main`.

1. Branch off `devel` (e.g. `feature/my-change`, `fix/my-bug`).
2. Open a PR into `devel`. The CI workflow (lint + build) runs automatically.
3. **Always merge with "Squash and merge"** — never "Rebase and merge" or "Create a merge commit". Every PR must land as a single commit so semantic-release can read the history correctly.
4. Give the PR a [Conventional Commits](https://www.conventionalcommits.org/) title, since it becomes the squash commit message:
- `feat: ...` → minor version bump
- `fix: ...` → patch version bump
- `feat!: ...` or a `BREAKING CHANGE:` footer → major version bump
- `chore:`, `docs:`, `refactor:`, etc. → no release
5. When `devel` is ready to ship, open a PR from `devel` into `main` and squash-merge it the same way. The push to `main` triggers the release workflow, which runs semantic-release to tag a version and publish a GitHub release from the commit history.

`main` and `devel` are both protected branches: direct pushes, force-pushes, and branch deletion are blocked, and all changes must go through a reviewed PR.

## License

Licensed under the [Apache License, Version 2.0](LICENSE).
14 changes: 0 additions & 14 deletions package-lock.json

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

Binary file added public/scotiabank-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 12 additions & 1 deletion src/data/resume.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,17 @@ export const DATA = {
},
},
work: [
{
company: "Scotiabank",
href: "https://www.scotiabank.com/",
badges: [],
location: "Toronto, Ontario",
title: "AI Engineer",
logoUrl: "/scotiabank-logo.png",
start: "Jun. 2026",
end: "Present",
description: "NDA",
},
Comment on lines +116 to +119

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

1. Scotiabank link blocked 🐞 Bug ≡ Correctness

The new Scotiabank work entry sets a truthy description ("NDA"), which causes ResumeCard to call
preventDefault on click and toggle expansion instead of navigating, making the provided Scotiabank
href unreachable from the card.
Agent Prompt
### Issue description
The Scotiabank ResumeCard is configured with an external `href`, but because `description` is non-empty, the ResumeCard click handler prevents default navigation and toggles expansion instead. This makes the Scotiabank link non-functional from the UI.

### Issue Context
`ResumeCard` is wrapped in a `Link` and attaches `onClick={handleClick}`. `handleClick` calls `e.preventDefault()` whenever `description` is truthy.

### Fix options
- **Simplest (data-only):** For the Scotiabank entry, omit `description` (or set it to an empty string) so the card click navigates to the href.
- **Behavioral (component):** Change `ResumeCard` so navigation is not prevented when `href` is provided (e.g., only toggle expansion via a dedicated control like the chevron).

### Fix Focus Areas
- src/data/resume.tsx[108-119]
- src/components/resume-card.tsx[34-46]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

{
company: "Microsoft",
href: "https://www.microsoft.com/en-ca/",
Expand Down Expand Up @@ -152,7 +163,7 @@ export const DATA = {
title: "Undergraduate Researcher",
logoUrl: "/ucalgary-logo.jpeg",
start: "Sep. 2025",
end: "Present",
end: "Apr. 2026",
description:
"I am building BridgeMart, a cross-chain data marketplace on Ethereum and Solana where anyone can list, discover, and purchase encrypted datasets without trusting a third party. The core of the system is a privacy-preserving vending pipeline: datasets are encrypted client-side, integrity hashes are stored on-chain, and a smart-contract-gated decryption-key release ensures buyers only decrypt what they have paid for. On top of that, I shipped a RAG-style discovery service that uses LLM embeddings to match natural-language queries against tabular dataset signatures, backed by a FastAPI/Pydantic API and consumed by React and React Native frontends.",
},
Expand Down
Loading