Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
fe458f5
feat: add local image to text OCR UI
maruson08 Sep 22, 2026
ac241ef
test: cover image to text workflows and routes
maruson08 Sep 22, 2026
ecc95ec
docs: record Sprint 16B OCR scope and QA
maruson08 Sep 22, 2026
5e68b06
fix: satisfy documentation whitespace gate
maruson08 Sep 22, 2026
77cc8db
docs: define v2.1 development workflow
maruson08 Sep 22, 2026
d555108
ci: enforce integration branch policy
maruson08 Sep 22, 2026
948e0de
Merge pull request #78 from SecureToolsProject/chore/v2.1-development…
maruson08 Sep 22, 2026
c58221f
Merge remote-tracking branch 'origin/v2.1' into feat/sprint-16b-image…
maruson08 Sep 22, 2026
74d152a
Merge pull request #77 from SecureToolsProject/feat/sprint-16b-image-…
maruson08 Sep 22, 2026
36f4ee6
test: extend v2.1 OCR release coverage
maruson08 Sep 23, 2026
8d3325f
docs: record v2.1 release hardening evidence
maruson08 Sep 23, 2026
edb0ade
Merge pull request #80 from SecureToolsProject/test/sprint-16c-v2.1-r…
maruson08 Sep 25, 2026
934d8ad
πŸ“„[Docs] Reinstate Secure Tools commit convention
maruson08 Sep 25, 2026
d829da3
βœ…[Test] Add commit message validation coverage
maruson08 Sep 25, 2026
89a6523
πŸ”§[Config] Enforce commit convention in CI
maruson08 Sep 25, 2026
9e959b6
Merge pull request #82 from SecureToolsProject/chore/enforce-commit-c…
maruson08 Sep 25, 2026
00a458e
πŸ›[Fix] Grandfather pre-enforcement commit history
maruson08 Sep 25, 2026
33f78e5
Merge pull request #84 from SecureToolsProject/fix/release-promotion-…
maruson08 Sep 25, 2026
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
35 changes: 35 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
branches:
- main
- v2
- v2.1

permissions:
contents: read
Expand All @@ -22,11 +23,45 @@ jobs:
with:
fetch-depth: 0

- name: Enforce pull request branch policy
if: github.event_name == 'pull_request'
shell: bash
env:
BASE_REF: ${{ github.base_ref }}
HEAD_REF: ${{ github.head_ref }}
run: |
if [[ "$BASE_REF" == "v2.1" ]]; then
if [[ "$HEAD_REF" =~ ^(feat|fix|test|chore)/.+$ ]]; then
exit 0
fi
echo "::error::Pull requests into v2.1 must come from feat/*, fix/*, test/*, or chore/* branches."
exit 1
fi

if [[ "$BASE_REF" == "main" ]]; then
if [[ "$HEAD_REF" == "v2.1" || "$HEAD_REF" =~ ^hotfix/.+$ ]]; then
exit 0
fi
echo "::error::Only v2.1 release promotion or an explicit hotfix/* branch may target main."
exit 1
fi

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 24

- name: Enforce commit and pull request title conventions
if: github.event_name == 'pull_request'
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
PR_TITLE: ${{ github.event.pull_request.title }}
COMMIT_CONVENTION_GRANDFATHER: edb0ade331c54f380ae33abe7816c5a92f3a590a
run: |
node scripts/validate-commit-message.mjs --range "$BASE_SHA" "$HEAD_SHA" --grandfather-through "$COMMIT_CONVENTION_GRANDFATHER"
node scripts/validate-commit-message.mjs --title "$PR_TITLE"

- name: Check changed files for whitespace errors
shell: bash
env:
Expand Down
39 changes: 39 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Repository workflow policy

## Protected branches

- `main` is production-only. `v2.1` is the active integration branch for the v2.1.0 development cycle.
- Never commit feature, fix, test, or chore work directly to `main` or `v2.1`.

## Development work

- Create short-lived `feat/*`, `fix/*`, `test/*`, or `chore/*` branches from `v2.1`.
- Sprint and routine development pull requests target `v2.1`, not `main`.
- After a successful merge, delete only the merged short-lived branch when cleanup is authorized.

## Commit messages

- Use exactly `<Gitmoji>[<Action>] <imperative subject>` for every human-authored commit. There is no space before `[Action]`, square brackets are mandatory, and exactly one space follows `]`.
- Use one fixed pair: `✨[Feat]`, `βž•[Add]`, `πŸš€[Deploy]`, `βœ…[Test]`, `πŸ“ˆ[Data]`, `πŸ›[Fix]`, `♻️[Refactor]`, `πŸ”§[Config]`, `🚨[Hotfix]`, `βš™οΈ[Chore]`, `πŸŽ‰[Init]`, `πŸ“„[Docs]`, `πŸŽ€[Style]`, or `🚚[Rename]`.
- Write a concise imperative subject for one logical change. Split unrelated changes into separate commits.
- Plain Conventional Commit prefixes such as `feat:`, mismatched pairs such as `πŸ›[Feat]`, and spaced forms such as `✨ [Feat]` are prohibited.
- Good: `✨[Feat] Add Image to Text OCR`, `βœ…[Test] Cover OCR cancellation`, `πŸ“„[Docs] Document release workflow`.
- Bad: `feat: add OCR`, `✨ [Feat] Add OCR`, `✨[Fix] Add OCR`.
- Inspect recent conforming history if uncertain. Do not create a commit until its message satisfies this convention.
- Commit creation does not authorize merging; the merge-authority policy below still applies.

## Merge authority

- Creating a pull request and merging it are separate operations.
- An agent must not merge its own pull request automatically. Passing CI does not authorize a merge.
- Merge only when the user explicitly requests that specific merge after review. Never enable auto-merge without an explicit request.

## Production promotion

- Normal development reaches `main` only through a dedicated release or hardening pull request from `v2.1`.
- Creating the v2.1.0 tag or release requires separate explicit authorization after final verification.

## Hotfixes

- Production hotfixes use a dedicated `hotfix/*` branch and pull request into `main`.
- Never push a hotfix directly to `main`.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Added

- Added the Sprint 16B Image β†’ Text OCR interface for the v2.1.0 development cycle with single-image PNG/JPEG/WebP input, English/Korean/combined recognition, editable results, copy, UTF-8 TXT download, cancellation, retry, orientation-correct previews, request-identity safeguards, and complete six-locale UI coverage.
- Added the internal Sprint 16A local OCR foundation with pinned, same-origin Tesseract.js 7.0.0 worker/core assets, English and Korean language data, orientation-aware image preparation, normalized progress, worker reuse, cancellation, cleanup, and real OCR smoke coverage. No public OCR tool was added.
- Started the v2 cycle with a production Image category and local Image Converter.
- Added Image Resize with pixel and percentage modes, aspect-ratio preservation, optional enlargement, Original/JPEG/PNG/WebP output, and local batch ZIP saving.
Expand All @@ -19,6 +20,7 @@

### Changed

- Hardened the v2.1.0 release candidate with real English, Korean, and combined local OCR smoke coverage plus reproducible browser, privacy, CSP, asset, locale, responsive, accessibility, and regression evidence.
- Hardened v2 promotion gates for all ten production tools, vendored-resource integrity, local-only network invariants, save failure paths, and resource boundaries.
- Upgraded secure-metadata to v0.1.1 so JPEG Privacy Clean preserves one valid rendering Orientation while removing other targeted EXIF/GPS data without decoding or re-encoding pixels.
- Aligned Image and PDF Metadata action panels and bounded their primary decoded summaries while retaining complete details.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ npm test
node tests/ocr-smoke.test.mjs
```

The public Image β†’ Text interface is not part of the current production surface. The reusable local OCR runtime is documented in [Local OCR foundation](./docs/ocr-foundation.md).
The Image category includes a public, single-image [Image β†’ Text OCR](./tools/image/to-text/) workflow for PNG, JPEG, and WebP input. English, Korean, and combined English + Korean recognition run through the same-origin OCR runtime documented in [Local OCR foundation](./docs/ocr-foundation.md).

## Documentation

Expand Down
4 changes: 4 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ The root [README](../README.md) introduces Secure Tools. This directory owns det
| Document | Responsibility |
| --- | --- |
| [Architecture](./architecture.md) | Static application structure, shared browser foundations, delivery, and future ecosystem direction |
| [Development workflow](./development-workflow.md) | Production, integration, Sprint, release, hotfix, merge-authority, and branch-cleanup rules |
| [Privacy model](./privacy-model.md) | Local-processing and network boundaries, storage, security controls, and bounded privacy claims |
| [Dependencies](./dependencies.md) | Production runtime inventory, versions, vendoring, licenses, and integrity ownership |
| [Local OCR foundation](./ocr-foundation.md) | Self-hosted Tesseract assets, languages, lifecycle, cancellation, caching, and privacy guarantees |
| [Sprint 16B Image β†’ Text QA](./sprint-16b-qa.md) | Automated and Chromium browser evidence for the v2.1.0 Image β†’ Text workflow |
| [Sprint 16C v2.1.0 release hardening](./sprint-16c-v2.1-release-hardening.md) | Release-candidate regression, OCR, privacy, browser, performance, and readiness evidence |
| [v2.1.0 release notes draft](./v2.1.0-release-notes-draft.md) | Unpublished release-note copy for the later promotion and release task |
| [Tool status](./tool-status.md) | Production and planned surfaces, supported formats, behavior, and resource boundaries |
| [Search discovery and metadata](./seo.md) | Canonical routes, crawler files, metadata policy, maintenance, and submission steps |
| [Cloudflare Pages migration bridge](./cloudflare-pages-bridge.md) | H3.2/H3.3 provenance plus the prepared H3.5 hostname-specific indexing, activation, validation, and rollback contracts |
Expand Down
6 changes: 3 additions & 3 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Production routes load application code and pinned libraries from the same origi
The homepage points to stable category hubs instead of maintaining a flat list of every utility:

- PDF: six production tools;
- Image: four production tools;
- Image: five production tools, including Image β†’ Text OCR;
- Privacy: a cross-category hub for the two metadata tools;
- Scan/OCR and Media: planned, non-interactive surfaces.

Expand Down Expand Up @@ -44,7 +44,7 @@ The current production inventory and tool-specific behavior live in [tool status
- `js/i18n.js` resolves six supported languages, applies translations without reload, updates document metadata and `<html lang>`, and preserves tool state when language changes.
- `js/config.js` centralizes repository links.
- `tools/shared/` owns common file admission, signature validation, image/PDF helpers, queue conventions, local save behavior, and shared tool presentation.
- `tools/shared/ocr.js` owns language selection, same-origin OCR paths, normalized progress, orientation-aware image preparation, worker reuse, cancellation, and disposal. It is infrastructure only and is not linked from the public tool surface.
- `tools/shared/ocr.js` owns language selection, same-origin OCR paths, normalized progress, orientation-aware image preparation, worker reuse, cancellation, and disposal for the public Image β†’ Text workflow.
- The File System Access API is used when available; a revoking Blob-download fallback serves other browsers.

Tool implementations retain specialized models when their workflows differ. Organizer uses a page grid and PDF rendering lifecycle; Metadata tools use bounded inspection models and fail-closed output verification. Shared UI does not erase these tool-specific guarantees.
Expand All @@ -57,7 +57,7 @@ Image conversion, resizing, and compression use browser decode, Canvas, and enco

## Development and delivery

Serving the committed production tree requires only an HTTP server. Reproducing OCR assets and running the full CI checks requires Node.js 24 and the exact lockfile. `npm run build` verifies prepared OCR assets, `npm test` runs the static and unit suite, and `node tests/ocr-smoke.test.mjs` performs real English recognition.
Serving the committed production tree requires only an HTTP server. Reproducing OCR assets and running the full CI checks requires Node.js 24 and the exact lockfile. `npm run build` verifies prepared OCR assets, `npm test` runs the static and unit suite, and `node tests/ocr-smoke.test.mjs` performs real English, Korean, and combined recognition.

`.github/workflows/ci.yml` validates pull requests and pushes to `main` using Node.js 24. It installs the lockfile only to reproduce and verify OCR assets, then checks commit-range whitespace, JavaScript syntax, unit coverage, and real local OCR without adding deployment behavior.

Expand Down
51 changes: 51 additions & 0 deletions docs/development-workflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Development workflow

Secure Tools separates product versions from Sprint numbers. A Sprint is a bounded unit of work within a product development cycle; it does not create a version, tag, or release by itself. Sprint 16B, for example, belongs to the v2.1.0 development cycle.

## Branch roles

- `main` is the production branch. Routine development does not target it.
- `v2.1` is the integration branch for the v2.1.0 cycle.
- Short-lived `feat/*`, `fix/*`, `test/*`, and `chore/*` branches start from `v2.1` and return through pull requests into `v2.1`.
- Direct feature or fix commits to `main` or `v2.1` are prohibited.

```text
main (production)
↑
release PR after hardening
↑
v2.1 (integration)
↑
Sprint PRs
↑
feat/* fix/* test/* chore/*
```

## Sprint delivery

1. Update local `v2.1` from `origin/v2.1`.
2. Create a short-lived branch from that exact integration state.
3. Commit and validate only the Sprint’s intended changes.
4. Open a pull request into `v2.1` and wait for required CI.
5. Treat review and merge as a separate step. An agent does not merge its own pull request or enable auto-merge unless the user explicitly authorizes that specific action.
6. After a successful merge and verification, remove the merged short-lived branch when branch cleanup is authorized.

## Commit convention

Human-authored commits use `<Gitmoji>[<Action>] <imperative subject>`. The prefix must be one fixed canonical pair: `✨[Feat]`, `βž•[Add]`, `πŸš€[Deploy]`, `βœ…[Test]`, `πŸ“ˆ[Data]`, `πŸ›[Fix]`, `♻️[Refactor]`, `πŸ”§[Config]`, `🚨[Hotfix]`, `βš™οΈ[Chore]`, `πŸŽ‰[Init]`, `πŸ“„[Docs]`, `πŸŽ€[Style]`, or `🚚[Rename]`.

There is no space between the Gitmoji and `[Action]`; exactly one space separates the closing bracket from a non-empty, concise imperative subject. Each commit represents one logical change. For example, `✨[Feat] Add Image to Text OCR` and `βœ…[Test] Cover OCR cancellation` are valid; `feat: add OCR`, `✨ [Feat] Add OCR`, and `✨[Fix] Add OCR` are invalid.

CI validates non-merge commits introduced by the pull request’s actual base-to-head range and validates the pull-request title with the same structural rule. Technical merge commits are excluded by their multiple-parent topology so normal merge commits remain supported. Published non-conforming history through `edb0ade331c54f380ae33abe7816c5a92f3a590a` is an explicit grandfather boundary: ancestors of that commit are excluded from later ranges, while every human-authored commit after it remains subject to validation. That history is retained and never rewritten solely for message compliance.

## Production release

After the v2.1.0 scope is integrated, complete release hardening and final verification on `v2.1`. Promote it through a dedicated `v2.1` β†’ `main` pull request. Only after that pull request is explicitly reviewed and merged may a separately authorized task create the v2.1.0 tag and release.

## Hotfixes

Urgent production fixes use a dedicated `hotfix/*` branch and pull request into `main`. They are never pushed directly. After production verification, carry the correction back into the active integration line as needed through an appropriate pull request.

## Enforced pull request policy

CI permits routine `feat/*`, `fix/*`, `test/*`, and `chore/*` pull requests into `v2.1`. Pull requests into `main` pass the branch-policy gate only when the head is exactly `v2.1` or a dedicated `hotfix/*` branch. The repository protects both long-lived branches with required pull requests, the existing `Validate static tools` check, resolved review conversations, blocked force pushes, and blocked deletion. Because the repository currently has one maintainer, an approving-review count is not required; explicit merge authorization remains mandatory.
Loading
Loading