diff --git a/docs/backlog/COR-104-verification-map.md b/docs/backlog/COR-104-verification-map.md index 06dc2689..6427618c 100644 --- a/docs/backlog/COR-104-verification-map.md +++ b/docs/backlog/COR-104-verification-map.md @@ -39,7 +39,7 @@ Trial findings are evidence of gaps only. A, level 2, measures 1 and 2. Core's index in `docs/north-star/rules/` starts with N2's 154 rules. -`just status` now counts 169 core rules and 13 template rules `Prose on purpose`. +On 2026-11-03, `just status` counted 169 core rules and 13 template rules `Prose on purpose`. `just test` checks both indexes: each enforcer links a file, or says `Prose only` or `Prose on purpose`. `just status` prints the `Prose only` count of each index, and `extensionrepo check` that of an extension. T1 marked 11 judgment rules `Prose on purpose` and deleted one rule that signoff replay enforces. diff --git a/docs/backlog/README.md b/docs/backlog/README.md index 10e2db28..08ecead3 100644 --- a/docs/backlog/README.md +++ b/docs/backlog/README.md @@ -7,7 +7,8 @@ This folder holds one file per extension or core item and the ordered delivery q ## Queue 1. COR-102 -2. COR-105 +2. XT-107 +3. COR-105 ## Plan rules @@ -60,6 +61,8 @@ Create no new M file. An extension maintained in its own repository, such as XT-101, keeps its cards in that repository's Epic. The exceptions are COR-103 and COR-104, which hold the verification cards of video-convert. +XT-107 is also an exception: its cards prove the template on a new extension, so they stay here. +A pull request here sets each of them to done, as [Cards](#cards) says. ## Make an item ready @@ -111,6 +114,7 @@ With no todo card, it becomes Shipped and leaves the queue. - [Markdown view](XT-103-markdown-view.md) - [Video convert](XT-101-video-convert.md) +- [Image shrink](XT-107-image-shrink.md) - [Video and image jobs](XT-602-video-image-jobs.md) ## Other deferred scope diff --git a/docs/backlog/XT-103-markdown-view.md b/docs/backlog/XT-103-markdown-view.md index 4ac4e99c..e63829e6 100644 --- a/docs/backlog/XT-103-markdown-view.md +++ b/docs/backlog/XT-103-markdown-view.md @@ -15,10 +15,10 @@ The candidate renders one Markdown file in the terminal. ### Everyday domains Pascal picked neither candidate in [M17](../milestones/M17-inventory.md) on 2026-10-19. -Both wait for the [extension template](../milestones/M18-extension-template.md). +The [extension template](../milestones/M18-extension-template.md) that both waited for shipped with M18. #### Markdown view Today, `just sk-read ` in Pascal's SKILLS_MONO repository prints a skill's raw Markdown. The candidate renders one Markdown file in the terminal. -Revisit as a default extension that wraps Glow once the extension template milestone is done. +Revisit as a default extension that wraps Glow. diff --git a/docs/backlog/XT-107-image-shrink.md b/docs/backlog/XT-107-image-shrink.md new file mode 100644 index 00000000..80e6ccd7 --- /dev/null +++ b/docs/backlog/XT-107-image-shrink.md @@ -0,0 +1,93 @@ +--- +id: XT-107 +extension: "image shrink" +state: "Ready. Epic 19, #494, owns the work in pascalandy/ncly-image-shrink" +--- + +# XT-107 image shrink + +## Demo + +`ncly image shrink photo.jpg` writes a smaller `photo.shrunk.jpg` beside the input, without its location, after a dry run. + +## Scope + +The extension ships in its own public repository, `pascalandy/ncly-image-shrink`, with its own versions. +[Epic 19, #494](https://github.com/pascalandy/nicely/issues/494) follows the work, and the milestone `XT-107 image shrink` holds its issues. +This is the first slice of [video and image jobs](XT-602-video-image-jobs.md). + +### The command + +- One job: make one image smaller to share it. Domain `image`, name `shrink`, slug `image-shrink`, as [Extension identity](../north-star/contract/extension-identity.md) defines +- One JPEG, PNG, or WebP file in. One file out, in the same format, at `.shrunk.` beside the input. The input never changes +- Success means that the output has fewer bytes than the input. Otherwise the command publishes nothing and fails with its own error code. An optimized PNG below the size limit is such a case +- The longest side becomes at most 2048 pixels by default, and one flag sets another value. The command never enlarges an image +- JPEG and WebP use a lossy quality setting. PNG stays lossless +- The output applies the orientation of the input and keeps its color profile +- The output removes the descriptive metadata: location, author, camera, and capture date. This is the purpose of a copy to share +- `--dry-run` previews the work, and `--force` replaces an existing output, as `ncly video convert` does +- No key, no network, and no cost + +The intake chooses the program that does the work, such as libvips or ImageMagick. +The program must install with Homebrew on macOS and with pacman on Omarchy. +The manifest declares it, and `ncly doctor` names its install command. + +### Template proof + +This item also proves the template on a new extension. +An agent new to this work builds it, up to "Done when" in the template's [AGENTS.md](../../template/AGENTS.md.jinja). +The video-convert adoption proved the loop on an extension that already existed. + +- An agent that did not read `ncly-video-convert` builds the command, from the template of the latest Nicely release +- The [`nicely-extension` skill](../../template/.agents/skills/nicely-extension/SKILL.md) of the new repository drives the work: intake, spec, a scenario that fails first, rounds, independent review, readiness review, and `just finish` +- When the template, the contract, or the SDK stops the agent, it opens an issue in this repository and links it in Epic 19. The issue has the label `2-type:bug` or `2-type:task` +- Nobody edits Nicely by hand to unblock the build +- The pull request names the author session and the reviewer session. [D069](../north-star/decisions/D069-recorded-sessions.md) designs their capture, and #451 will enforce it + +## Cards + +| Card | Title | Owner | Depends on | Status | +|---|---|---|---|---| +| XT-107-T1 | Create the repository from the template | agent | - | todo | +| XT-107-T2 | Build ncly image shrink through the loop | agent | XT-107-T1 | todo | +| XT-107-T3 | Release v0.1.0 | agent | XT-107-T2 | todo | + +### XT-107-T1 Create the repository from the template + +- **Read:** [nicely-extensions](../../extensions/skill/nicely-extensions/SKILL.md), [Extension repository](../north-star/contract/extension-repository.md) +- **Proves:** just check and the hosted checks, in ncly-image-shrink + +Create the public repository `pascalandy/ncly-image-shrink` with the Copier command of the `nicely-extensions` skill, at the tag that `ncly --version` prints. +Pass `domain=image`, `name=shrink`, and `module=github.com/pascalandy/ncly-image-shrink`. +Run `go mod tidy`, commit, and push. +`just check` passes on the rendered repository, and its GitHub workflow passes on Linux and macOS. + +### XT-107-T2 Build ncly image shrink through the loop + +- **Read:** `AGENTS.md` and the `nicely-extension` skill of the new repository, [What a great extension does](../north-star/contract/extensions.md#what-a-great-extension-does) +- **Proves:** intake.toml, spec.md, review.toml, and just finish, in ncly-image-shrink + +Build the command of [The command](#the-command) in one pull request, in at most 5 rounds, as the `nicely-extension` skill says. +Its acceptance cases use images that the tests make. +One of them holds a location that the output must not keep. +One of them cannot get smaller, and the command must refuse it without an output. +The card is done when `just finish` passes and the pull request merges. + +### XT-107-T3 Release v0.1.0 + +- **Read:** the [README](../../template/README.md.jinja) and the [justfile](../../template/justfile) that the template renders, and [delivery.md](../../template/.agents/skills/nicely-extension/delivery.md) +- **Proves:** the release receipt, in ncly-image-shrink + +Run `just signoff`, then `just release v0.1.0`. +Install the tag on om1 and on the Mini as the README says. +Install the program that the manifest declares on the Mini only with Pascal's consent. + +## After + +- A separate UAT issue: Pascal tells a fresh agent "Use Nicely to shrink the image ", then shares the result +- The cost of the build: rounds, findings, and the issues opened against Nicely. COR-104 After reviews the cost of the gates + +## Later + +- HEIC input, batches of images, and folders +- Other image jobs, such as crop or convert, each as its own named extension in the `image` domain diff --git a/docs/backlog/XT-602-video-image-jobs.md b/docs/backlog/XT-602-video-image-jobs.md index 24b91de5..18a2e924 100644 --- a/docs/backlog/XT-602-video-image-jobs.md +++ b/docs/backlog/XT-602-video-image-jobs.md @@ -1,12 +1,13 @@ --- id: XT-602 extension: "video and image jobs" -state: "Idea. Revisit after COR-102 ships: deliver one small useful slice through the loop" +state: "Idea. XT-107 image shrink delivers the first slice. Revisit another operation after XT-107 ships" --- # XT-602 video and image jobs Video and image commands encode, cut, extract audio, resize, or compress one selected input. +[XT-107 image shrink](XT-107-image-shrink.md) is the first slice, chosen by Pascal on 2026-11-06. ## Later diff --git a/docs/north-star/architecture.md b/docs/north-star/architecture.md index c8111b90..f3242cb4 100644 --- a/docs/north-star/architecture.md +++ b/docs/north-star/architecture.md @@ -30,7 +30,7 @@ flowchart TB host["3 · Core, the host
Dispatch, help, completion, describe, doctor, auth, run, tap
Application layer"] svc["2 · Services
Config, i18n, program runner, run records
Runtime layer"] contract["1 · Contract
Manifest, environment, answer, exit code, run record
Primitives and interface"] - platform["0 · Platform
Durable writes, locks, keychain, trash, process tree
Foundation"] + platform["0 · Platform
Durable writes, locks, keychain, process tree
Foundation"] end taps ~~~ ext ~~~ host ~~~ svc ~~~ contract ~~~ platform @@ -72,7 +72,7 @@ Each part has one owner: one package and one spec section. | 2 | i18n | Catalogs, lookup, plurals, and number, size, and date formats, and the SDK's own catalog | `sdk/i18n/` | [Configuration](contract/configuration.md) | | 2 | Interactive parts | The shared styles, forms, and screens | `sdk/tui/` | [dev-preferences.md](dev-preferences.md#decide-the-look-with-a-published-mockup) | | 1 | Contract | Answer, answer check, error registry, exit codes, modes, declarations, manifests, and streams | `sdk/contract/` | [contract.md](contract.md) | -| 0 | Platform | Durable writes, locks, trash, and process tree | `sdk/platform/` | [Record format](contract/record-format.md), [Programs that ncly runs](contract/programs-that-ncly-runs.md) | +| 0 | Platform | Durable writes, locks, and process tree. [COR-629](../backlog/COR-629-os-trash.md) would add the OS trash | `sdk/platform/` | [Record format](contract/record-format.md), [Programs that ncly runs](contract/programs-that-ncly-runs.md) | | 0 | Keychain | Keys in the OS keychain, which reach an extension only through grants, and the time limit of each keychain call | `internal/keychain/` | [Keys](contract/keys.md), [Programs that ncly runs](contract/programs-that-ncly-runs.md) | A later shared service starts in `sdk/`. Core keeps in `internal/` only what an extension never runs: the host, core's commands and catalog, and the keychain. [The backlog](../backlog/README.md) records when each implementation arrives. @@ -99,9 +99,9 @@ Each correction lands at the highest of four verification levels that can preven | `skill` | Lists, views, and checks skills for agents, including the bundled `nicely` skills | bundled | | `agent` | Runs one trusted Codex task with model and effort settings | external | | `transcript` | Transcribes one selected YouTube video | external | -| `docs` | Shows selected project docs in one local site | external | +| `docs` | Would show selected project docs in one local site. See [XT-104](../backlog/XT-104-docs-hub.md) | external | [Command tree](core-spec.md#command-tree) lists the names that core reserves. `transcript` is not the first thing a visitor should try, because it needs a Deepgram key. M17 selected neither everyday candidate. [M18](../milestones/M18-extension-template.md) shipped the extension template before any particular extension. -The backlog tracks [Markdown view](../backlog/XT-103-markdown-view.md) and [additional video and image jobs](../backlog/XT-602-video-image-jobs.md). +The backlog tracks [Markdown view](../backlog/XT-103-markdown-view.md), [image shrink](../backlog/XT-107-image-shrink.md), and [additional video and image jobs](../backlog/XT-602-video-image-jobs.md). diff --git a/docs/north-star/contract/extension-repository.md b/docs/north-star/contract/extension-repository.md index 169c8548..22d7bde3 100644 --- a/docs/north-star/contract/extension-repository.md +++ b/docs/north-star/contract/extension-repository.md @@ -36,7 +36,7 @@ The template refuses `main` and each Go keyword as a domain, such as `type`. It A push can skip Lefthook, so its GitHub workflow runs `just check` again on `ubuntu-24.04`. Public repositories also run the same steps on `macos-15`, and both runners are free. -The repository tests itself through the [test kit](test-kit.md). Its `justfile` has eleven recipes: +The repository tests itself through the [test kit](test-kit.md). Its `justfile` has twelve task recipes, plus `default`: - `just check` runs every check: `go mod tidy -diff`, `gofmt`, `go vet`, the [analyzers](analyzers.md) of the pinned SDK, and `go test`, whose test kit installs the extension into scratch folders. With `verification/tlc.json`, it first reads the record of the [models](formal-models.md). It first prints how many rules of the rule index are `Prose only` - `just finish` is the exit of the loop of the skill, and `just check` stays green for an incomplete round. [Finish gate](finish-gate.md) lists what it checks