昨年 4 月 1 日に、Kintaman という SaaS のプロジェクトの始動を発表しました。 勤怠タスクマネージャ Kintaman 始動 リモートワークと人事評価をラクに
Kintaman は勤怠とタスクを一括管理する SaaS で、日々のパフォーマンスを記録・分析・改善し、従業員の業務を効率化します。AI による自動化や客観的な評価支援、ノーコードでのデータ処理など、業務効率化のための包括的なソリューションを提供します。
本記事では、Kintaman のビジョン、歴史、ティザーサイトに関することをご紹介します。
Kintaman のビジョン
Kintaman Core
この資本主義社会は労働と密接にリンクしています。生まれてから一度も金銭を対価に他人の下で労働をしたことがない、という方は少ないでしょう。不可能とはいいませんが労働から逃れることは難しいです。
この世の中には様々な仕事があります。業種、職種、雇用形態、など様々な職業が存在し、行う仕事も多種多様です。
しかし、どのような仕事でも共通して存在するのが「時間」と「タスク」です。あらゆる仕事は時間を要し、何らかのタスクを伴います。本来、勤怠管理(時間の管理)とタスク管理は不可分な関係にあるはずです。
しかしながら、現状の多くの企業では勤怠管理とタスク管理が分断されています。
勤怠管理は勤怠管理システム、タスク管理はタスク管理システム、というように、単一のドメインにのみフォーカスするシステムが多いです。 そして、企業も場当たり的に一つの課題を解決するためにそのようなシステムを個別に導入する傾向にあります。
たしかに目に見える課題は解決できています。しかし、現在さまざまな SaaS が存在する中で、市場は飽和状態にあります。単に場当たり的に課題を解決するだけではもう通用しません。より本質的な、全体最適な解決策が求められています。
業務のドメインモデルにおいて、「時間」と「タスク」は密接不可分な、業務における両輪であって、本来は一つのシステムで管理されるべきものです。 これまでの業務支援システムは、個別の課題に対してそれぞれ独立したソリューションを提供してきました。しかし、そのアプローチでは業務の本質的な構造を反映できていません。 勤怠管理とタスク管理を個別のシステムで扱うことは、長い目で見れば、業務の効率化を妨げる要因となります。
私自身、タイムカードを押し、タスク管理ツールを開いてタスクにかかった時間を報告し、日報を書くために別のツールを開く、といった煩わしい経験をしてきました。 その際に「時間」と「タスク」という本質に気づき、それが分断されていることに疑問を覚え、解消したいという思いを抱くようになりました。すなわち、勤怠管理とタスク管理を一体化した新しいシステムの必要性を認識するに至りました。 そのようにして、「勤怠管理」と「タスク管理」、あわせて「勤怠タスクマネージャー」、略して「Kintaman」(現在の Kintaman Core)を考案するに至りました。
KintamanAi と Kintaman Companion
デスクワーク中心の現代の業務環境において、私たちの行動の多くはデジタルに記録可能なものとなっています。記録しようと思えば、キーボードの入力、マウスの操作、ブラウザの閲覧履歴、Git のコミットなどさまざまな日々の業務トレースを残せます。 コンピュータで行われた作業であれば、作業のリプレイが可能というわけです。
ただ、そのトレースログを残したところで、確認するのに作業と同じほどの時間を要するのでは意味がないと考えられてきました。 日々の記録を残すために、日報を書いたり、タスク管理ツールに記録したりしていました。 今まで何の疑問も持たずに、日報を書くなどを当然のように行ってきましたが、その作業自体も自動化できる余地が生まれてきました。
近年、ChatGPT をはじめとした LLM(大規模言語モデル)の進化により、人間が今まで行ってきた文章生成タスクをコンピュータで十分代替できるようになってきました。日報作成やタスクの記録も十分に可能なほどの精度を持っています。 これがあれば、人間が確認しなくともコンピュータにトレースログを読ませ、業務のふりかえり分析をさせればよいわけです。 トレースログを基に LLM に業務を分析させ、日報を作成したり、過去のタスクを記録したり、タスクの進捗を可視化したり、まだ起票されていないタスクを洗い出すことまでできてしまうでしょう。これを実現するのが Kintaman Companion と KintamanAi です。
Kintaman Companion では、従業員の作業ログを収集・分析します。具体的には、PC の操作履歴、ブラウザの閲覧履歴、Git のコミット履歴などから、行われた作業の痕跡を追跡します。
そして、KintamanAi がこれらのログを解析し、タスクの自動生成や日報の作成を行います。これにより、従業員は作業記録に時間を費やすことなく、本来の業務に集中できるようになります。 例えば、ブラウザのタブ一覧やコミットログなどから、適切なタスクとして整理します。「このコミットは新機能の実装に関するものだ」「これらのタブは障害調査のために開かれていた」といった具合に、作業の意図を推測し、その日に行った作業の文脈を理解し、作業をタスクとして整理し、その日の業務内容を簡潔にまとめた日報を自動で作成します。さらに、次のタスクを提案したりすることもできます。
Kintaman Ξ
私は Kintaman を考案した当時、STEPN にハマっていました。STEPN は、歩くことでお金を稼げ、アイテムを売買できるブロックチェーンゲームです。STEPN は、GST, GMT, スニーカーの NFT、SOL、と、複数のトークンが複雑に絡み合ったエコシステムを持っていることが特徴です。Axie Infinity の Play to Earn から派生した Walk to Earn という新しい概念を生み出し、世界中で大流行しました。
何かをすると驚くことにお金がもらえる Tokenomics 設計の総称 X to Earn の流れで、私は Work to Earn という概念を思いつきました。働くことでお金を稼げる、というギャグです。何の意外性もないですね。 そこにちょうど Kintaman のアイデアを思いついたことで、相性のよさを感じ、そのギャグをギャグから発展させて実際に実現してみようと思いました。
Kintaman Ξ は、STEPN にインスパイアされた Work Unit(WU)、Time Unit(TU)、そして日本円(JPY)の 3 つのトークンを用いたエコシステムを持ち、従業員間での PvP バトルを促進し、労働のアービトラージが可能なトークンエコノミーを実現します。
単に会社から毎月給料を貰える、それだけのつまらないモデルではなく、より生産的で意欲的な働き方を喚起できる仕組みを目指します。 まあ従業員間でバトルが起こるということなので、ギスギスすることになるかもしれませんが。
名前について
Kintaman は、KINtai(勤怠)、TAsk(タスク)、MANager(マネージャー)の略であると同時に、「金貯まん」、「金」と、「貯まる」の未然形、つまり、将来お金が貯まるかもしれない、という意味を込めました。
まあ、現代日本語で、未然形の後に続く単語は「ない」以外ほぼないんですけども。とくに「ん」になる場合。
Kintaman の歴史
Kintaman の歴史は、AokiApp が誕生するよりも昔の、2022 年 11 月に遡ります。当時既に現在の Kintaman ティザーサイトとほとんど同じコンテンツ・レイアウト・デザインの Adobe XD のプロトタイプが完成していました。 大学で Adobe Creative Cloud を使ったデザインの授業があり、ライセンス狙いで受講しており、その際の期末制作で作ったものです。
ドメイン名 kintaman.co の歴史はもっと古く、2021 年 10 月 17 日に取得し、kintaman.co 、ao.kintaman.co、yu.kintaman.co の 3 つのサブドメインが動いていました。
友人が私に「あおきんたまんこ」という渾名を付けてくれました。また、Discord の絵文字も作ってくれまして、リアクション芸として定着しました。
「あおき」→「あおきん」→「あおきんたま」→「あおきんたまんこ」
その後、ドメイン芸をしたいなと思い、kintaman.co を取得しました。AokiApp のドメイン名である aoki.app よりも古いです。というか、実は aoki.app は 1000 ドルでドメインスクワッターから買ったものです。aoki.appと kintaman.co のドメインは同じタイミングで Google Domains のカートに入れておりました。気まぐれに kintaman.co の方は先に購入し、aoki.app の方はカートに放置していたところ、ドメインスクワッターに買われてしまいました。泣く泣く 1000 ドルで買い戻しました。ドメインスクワッターは本当にクソです。そういうわけで、kintaman.co の方が歴史が古いです。
それとは関係なく、「勤怠タスクマネージャー Kintaman」を思いつき、そのままドメインを流用しました。
その後、2023 年 3 月に、未踏に Kintaman、当時の名称は「Tamaki」、を応募しました。結果は一次落ちでした。非常に残念です。
そして、2024 年 4 月 1 日、ティザーサイトを公開するに至りました。
Kintaman のティザーサイト
Kintaman のティザーサイトは、複数のドメイン名を組み合わせて利用しています。
URL | 内容 |
---|---|
https://kintaman.co/ | トップページ |
https://kintaman.co/re | Kintaman Core |
https://kintaman.co/mp | Kintaman Companion |
https://kintaman.ai | KintamanAi |
https://kintaman.co/xi | Kintaman Ξ |
https://ao.kintaman.co | Kintaman Blue |
https://yu.kintaman.co | Kintaman You |
https://kintaman.ai/yo | ネタバラシ |
https://aoo.kintaman.co/ | Kintaman App |
さらに、?lang=ja
または ?lang=en
を URL に付与することで、言語ごとのページがあるので、18 ページくらいあります。
もし kintaman.io
を取得していたとしたら、 Kintaman You は kintaman.io/u
とすることができたでしょう。ドメイン芸をするためだけに ai ドメインに加えてさらに io ドメインも購入するとなると、お金が掛かり過ぎるので、やめました。
ドメインは一生ついてまわるもので、下手に手放してリンク切らすとドメイン警察に怒られてしまいますから安易に買うべきではありません。
Kintaman App のドメイン名が aoo.kintaman.co である理由について、最初、app.kintaman.co
にしようと思ったのですが、ちょうどキーボードの O
と P
が隣り合っているものですから、指がずれてついうっかり aoo
と打ってしまい、そのまま DNS レコードを設定してしまいました。変えるのもまた面倒なので、そのままにしています。
制作
Plasmic でページをデザインし、Next.js の Catch-all Router を使ってドメイン名ごとに振り分けています。
Plasmic については、 こちらを参照してください。誰でも React で Web アプリを作れる素晴らしいノーコードツールです。
ソースコード
import React from "react";
import { GetServerSideProps } from "next";
import PlasmicHomepage from "../components/plasmic/kintaman/PlasmicHomepage";
import PlasmicCore from "../components/plasmic/kintaman/PlasmicCore";
import PlasmicCompanion from "../components/plasmic/kintaman/PlasmicCompanion";
import PlasmicAi from "../components/plasmic/kintaman/PlasmicAi";
import PlasmicTry from "../components/plasmic/kintaman/PlasmicTry";
import PlasmicXi from "../components/plasmic/kintaman/PlasmicXi";
import PlasmicBlueSignup from "../components/plasmic/kintaman/PlasmicBlueSignup";
import PlasmicYouSignup from "../components/plasmic/kintaman/PlasmicYouSignup";
import { LangContext } from "../components/plasmic/kintaman/PlasmicGlobalVariant__Lang";
const routeTable: Record<string, React.ComponentType> = {
"kintaman.co/": PlasmicHomepage,
"kintaman.co/re": PlasmicCore,
"kintaman.co/mp": PlasmicCompanion,
"kintaman.ai/": PlasmicAi,
"kintaman.ai/yo": PlasmicTry,
"kintaman.co/xi": PlasmicXi,
"ao.kintaman.co/": PlasmicBlueSignup,
"yu.kintaman.co/": PlasmicYouSignup,
};
export const getServerSideProps: GetServerSideProps = async (context) => {
let { xdr, lang } = context.query;
let hostname = context.req.headers.host;
let debug = false;
console.debug("Query", context.query);
if (hostname === "localhost:3000") {
debug = true;
}
// get cookie
const cookie = context.req.headers.cookie;
// get lang from cookie
const langFromCookie = cookie
?.split(";")
.find((c) => c.trim().startsWith("lang="));
// if lang is not found, get lang from query
lang = lang || langFromCookie?.split("=")[1];
// if lang is not found, set lang to "en"
lang = lang || "en";
// set lang to cookie
context.res.setHeader("Set-Cookie", `lang=${lang}; Path=/; HttpOnly`);
// normalize xdr
if (!xdr) {
// if xdr is undefined, it is the root path
xdr = [];
} else if (typeof xdr === "string") {
// if xdr is a string, it is a single element
xdr = [xdr];
}
// redirect check
// Trigger redirect if URL is like "https://kintaman.co/kintaman.ai/yo" or "https://kintaman.ai/kintaman.co"
// thus, we need to check if the first element is domain style
const firstElement = xdr[0];
if (firstElement?.includes(".")) {
// okay it's a domain style, let's redirect
let redirectUrl = debug
? "http://localhost:3000"
: `https://${firstElement}`;
if (xdr.length > 1) {
redirectUrl += `/${xdr.slice(1).join("/")}`;
}
redirectUrl += `?lang=${lang}`;
console.debug("Redirecting to", redirectUrl);
return {
redirect: {
destination: redirectUrl,
permanent: true,
},
};
}
// dynamic route phase
// compose the route key
if (debug) {
hostname = "kintaman.co";
}
// pop if the last element equals to "index"
// Why do I need to do this? Because...
// When Next.js tries to render a page with a trailing slash with client-side navigation,
// it will use `index.json` endpoint to fetch the props. This cause the xdr to have an extra "index" element.
// which is not done in server-side navigation, since the pure (no index, end with slash) path is used.
// This is a workaround to fix the issue.
if (xdr[xdr.length - 1] === "index") {
xdr.pop();
}
const path = xdr.join("/");
const routeKey = `${hostname}/${path}`;
console.debug("Routing to", routeKey);
return {
props: {
routeKey,
lang,
},
};
};
export default function CrossDomainRouter({
routeKey,
lang,
}: {
routeKey: string;
lang: "ja" | "en";
}) {
const Component = routeTable[routeKey];
return (
<LangContext.Provider value={lang}>
<Component />
</LangContext.Provider>
);
}
export const runtime = "experimental-edge";
結局のところ Kintaman はどうなったの?
Kintaman は、プロジェクトのキックオフがなされたということになっておりますが、結局のところ、特に進捗はございません。やはり、目指すものが大きすぎ、簡単に目指せるものではないからです。 また、現実的な解を見つけてしまったからです。Lark というツールに感動してしまい、Kintaman の必要性が薄れてしまいました。
昨年より弊社では Lark というツールを利用しています。Lark は、TikTok で有名な ByteDance が開発した、Notion, LINE, Asana, Airtable, Miro, Google Calendar, Zoom, Gmail, 勤怠管理ツール, ジョブカンワークフロー を足し合わせ、それぞれを密に統合したようなツールです。 単独の機能としても他社に引けを取らないクオリティであるうえ、各機能が密に統合され、シームレスな業務体験を提供しています。
タスク機能が非常に秀逸で、Kintaman で実現したかったレベルのタスク管理がほぼほぼ実現できてしまっています。さらに、勤怠管理とも連携し、その結果がメッセージに集約されるので、Kintaman Core の機能もある程度実現できています。 「もうこれでええやん」と思いましたね。AokiApp では Lark 使いまくりです。Microsoft 365 解約しちゃいました。Lark が最高であるという話のつづきは別の記事で書こうと思います。
あと、そもそも、タスク管理ってどれだけ手を尽くしてもめんどくさいのはめんどくさいよねという諦めの境地に達しつつあるというのもあります。私自身、セルフマネジメントをやりきれていないところがあり、仮に Kintaman が存在したとしても、究極的には使用者のマインドで、どうしようもないのだなと感じてきました。
もし、Kintaman に共感していただき、Kintaman を欲しい!と感じて頂けた方がいましたら、開発に着手し、ご提供させていただければと存じます。
まとめ
1 年越しに、Kintaman について答えあわせ記事を執筆させていただきました。
Kintaman に対する私の思いをお伝えできたでしょうか。Kintaman がエイプリルフールではないということがご理解いただけたと思います。 また、手の込んだティザーサイトを作成し、ドメイン芸をしました。皆さんはドメイン名についてどこまで気づきましたか?
エイプリルフールに発表したプレスリリースではありましたが、その背景には確かな問題意識と真摯な取り組みがあったことをお伝えできれば幸いです。