The org's wallpaper behind every page, and white copy on it
kamo-sign was the one white-labelled surface still painting a flat grey. It now plays the inviting organization's background photography the way kamo-login, kam...
Publish the packages from CI, with a token that can actually publish
The secret exists now β a Forgejo token scoped to `write:package`, added to this repository β so `publish_packages` does the publishing instead of a person doin...
Why AssuranceLevel only ever reports SES
ESigService reports SES and only SES now. eIDAS Article 26 lets a signature call itself ADVANCED only if the signature creation data is something the signatory ...
A compact trigger for the signed-copy menu
The sender's envelope list and any table of assigned packages have a row, not a hero slot, and the labelled pill does not fit one. `iconOnly` gives the SAME men...
The Β§ 7001(c) disclosure ships with the code, in twenty-two languages
`@kamo/esign-core` now carries the consumer disclosure itself β six clauses, every language the product signs in, and `consentDisclosure(locale, brand)` to fill...
Publish the packages from a job of their own, and never nest a second pdf.js
The publish steps sat inside `build`, so run 12014 failed and took the image with it β and `pnpm install --frozen-lockfile` was clean locally, which is the tell...
One signing surface for both apps, and the white label finally paints
The signing UI existed twice β here, and hand-copied into kamo-internal's legal execution wizard β and the two had drifted in both directions. `@kamo/esign-core...
Render the Signature Date field, and make readOnly mean something
Three changes, of which only the first is new work. **`signature_date`** is a field ESigService fills at the instant the signer signs β never the browser, whos...
Prove the deploy by digest, not by tag
The preceding commit stops `set image` being a silent no-op. This asserts the outcome: after the rollout, the tag is resolved to a digest at the registry and th...
A rebuild of the same commit deployed nothing and reported success
The image is tagged with the commit SHA, so rebuilding the same commit produces an identical image reference. `kubectl set image` then changes nothing, the Depl...
Let a rollout finish what the old pod was doing
preStop sleeps 10s before the process sees SIGTERM. Kubernetes removes the pod from its EndpointSlice and signals it at the same moment, and Traefik only learns...
Draw a rectangle's fill in the signer's view
The designer can now give a rectangle a fill and an opacity, which is how a member covers something up. This renderer drew fill="none", so the signer saw an emp...
Keep an option card and its lines off a page break
The per-option line table was added without the page-break rules its sibling table has, so a long option could be cut across pages mid-row.
Read either address shape so the block cannot go blank
Reading only the new addressLines makes the address disappear when the API has not been rebuilt yet and is still sending addressLine plus addressDetails. A blan...
Print the address as the lines it is written on
The address arrived as one string, so a real one came out as '4300 West Tropicana Ave Building A Main Floor Suites 110-132, Las Vegas, NV 89103' β not something...
The suite on its own line, and a setup fee on a single-price quote
Two things the printed page could not say. An address arrived as one comma-joined string, so 'Suite 400' ran into the street and the city β not how an address ...
Print the full line on the customer's quote
Each line showed a name and an amount. That asks the customer to take the quantity, the unit, the rate and any reduction on trust, and leaves them nothing to ch...
A committed term is worth what it commits to
The card led with the recurring rate whatever the term, so a three-year commitment priced at $100 a month was presented to the customer as $100. It is $3,600, a...
Show the whole term when the seller bills up front
The card led with the recurring rate regardless, so a customer signing a three-year deal payable at signing saw a monthly figure and a separate total below it. ...
State the first invoice on an option that has a setup fee
The card already listed the setup fee, but the only figure that summed it with the period price β the total over term β was gated on the commitment running long...
Format the phone numbers on the customer's quote
The page a customer opens printed every number exactly as stored β "9495550134" on the letterhead, and the same again under Your Contact. This app had no phone ...
Print the seller's ACH details on the customer's quote
The page a customer opens from a share link now carries a remittance block: who the payment is made out to, the receiving bank, and the routing and account numb...
Stop ignoring markdown
The "no .md in repos" rule is retired; docs, plans and READMEs are tracked like any other source file.
A signing page wears the sender's brand, not Kamo's
getThemePath took a hostname and used its FQDN with dots turned into dashes as the bucket folder. That could only answer for an org that HAD a hostname, and a d...
A party who already signed gets their copy, not the document again
The session always started at "welcome", so a signer following the link in their completion email β or simply reopening the invitation β was walked through the ...
Group an imported radio field's buttons natively
The buttons of one AcroForm radio field are imported as separate linked fields, one choice each, so each keeps its own box on the page. They were named after th...
Show the agent's phone, toll-free and email on the customer's copy
Show the assigned agent on the customer's copy
Matches the staff preview: the letterhead names the org, this names the person to ask.
Show the client's details on the customer's copy
Company heads the block when there is one β a quote to a business is addressed to the business, with the contact named beneath it. Matches the staff preview exa...
Compare options on the public quote page
Options render as selectable cards rather than rows, because they are choices and not additions. The period total is the headline; the monthly equivalent sits b...
Public branded quote/estimate document at /{locale}/q/{token}
The customer-facing surface for the commerce quote system. Server-rendered so the org's branding is in the first paint β an unbranded flash on a commercial docu...
Make the kubectl install resilient to flaky egress
With the PATH bug fixed, the deploy then failed on a transient TLS drop while downloading kubectl: curl: (56) OpenSSL SSL_read: error:0A000119:decryption fail...
Invoke kubectl by absolute path in the step that installs it
Root cause of deploy_k1m1 never succeeding. The install step did: echo "$BIN" >> "$GITHUB_PATH" kubectl version --client but $GITHUB_PATH only applies to SU...
Point the deploy kubeconfig at the LAN IP, not the k1m1 hostname
deploy_k1m1 had never succeeded (0/5 since the repo was created). The job rewrote the kubeconfig API server to https://k1m1:6443, but the runner's job container...
Re-trigger deploy after fixing K1M1_KUBECONFIG_B64
The deploy_k1m1 job had never succeeded (0/5) because the secret held k1m1's on-host kubeconfig verbatim, whose server is https://127.0.0.1:6443 β reachable fro...
Render signer dates in the recipient's resolved timezone
SigningSession gains a required `timeZone` (IANA id) that ESigService resolves from the recipient's member zone, then the org's, then UTC. WelcomeScreen now pas...
Disable hreflang alternates header; make LANGUAGE_NAMES total
- routing.ts: set alternateLinks: false β the app is noindex/nofollow with no consumer for the Link: rel=alternate header next-intl emits by default for all...
Clone translations from the dictionary, stop tracking messages/
Adds the dictionary clone step before the Docker build and gitignores apps/kamo-signer/messages/, matching kamo-internal and kamo-marketing. Requires **********...
Add language switcher to the signer top bar
Endonym-labelled menu over the 22 supported locales. Preserves the query string on switch β ?t= is the signer's only credential.
Mirror layout for RTL locales via stylis-plugin-rtl
The MUI theme direction alone flips component logic but leaves physical CSS properties untouched, so Arabic rendered with LTR spacing. Swaps the Emotion cache k...
Route the signer under /{locale} with next-intl middleware
Adds i18n/routing.ts (localePrefix always), i18n/navigation.ts, and middleware.ts, and moves the route tree under src/app/[locale]/. request.ts now resolves fro...
Implementation plan for the kamo-signer i18n upgrade
Seven tasks across kamo-translation-dictionary, kamo-signer-monorepo and ESigService, ordered by the deploy constraint: dictionary must exist before CI clones i...
Design for kamo-signer /{locale}/ i18n upgrade
Specifies bringing kamo-signer to platform i18n parity using the kamo-marketing /{locale}/ URL convention, as the prerequisite for hosting a localized public qu...
Drop dead deploy_k2m1 job, rebuild to k1m1 registry
kamowebsigner ran on a stale cached k0m1:5000 image, never re-pushed to the k1m1 registry after k0m1 retirement; disk-pressure eviction wiped the cache (ImagePu...
Install turbo via npm in Docker pruner stage; pin pnpm; add .dockerignore
The pruner stage ran `pnpm add -g turbo` before any package.json existed, so corepack grabbed pnpm 11 and failed with "global bin directory /pnpm/bin not in PAT...
New monorepo + mobile-first e-signature signing app
Turborepo + pnpm workspaces monorepo housing reusable e-sign packages extracted from kamo-internal plus a new, ultra-polished kamo-signer app β the second-party...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.