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
73 changes: 53 additions & 20 deletions .github/workflows/install-proof.yml
Original file line number Diff line number Diff line change
Expand Up @@ -505,11 +505,19 @@ jobs:
# anonymous release job cannot read the checked-in contract script, so it
# repeats the observable behavior; the authority test keeps it aligned
# with scripts/assert-windows-init-contract.sh.
#
# A populated directory with no Git history is the one boundary where
# this step and that script differ. The script runs against a binary
# built from source and requires admission. This step installs whichever
# release is public, and releases through v0.8.6 refuse that directory,
# so it takes either answer and holds the binary to the whole contract of
# the answer it gave.
- name: Windows admission contract proof
if: runner.os == 'Windows'
shell: bash
run: |
set -euo pipefail
POPULATED_UNCOMMITTED="Uncommitted work:"
NON_EMPTY_REFUSAL="requires an empty directory"

scratch="kin-windows-admission"
Expand Down Expand Up @@ -634,25 +642,21 @@ jobs:
git -c core.hooksPath= -c commit.gpgsign=false commit -qm probe
)
}
# Admit a fixture under the default (central) layout, or under
# `in-tree` when the fourth argument says so. A new store is central
# and the tree carries nothing, so publication is what `kin store
# path` discovers.
require_admitted() {
local layout="${4:-central}"
# What an admission that reported success must have published, under
# the layout the fourth argument names. A new store is central and
# the tree carries nothing, so publication is what `kin store path`
# discovers.
require_published() {
local home
local store
home="$(fixture_home "$2")"
if ! fixture_kin "$2" "$layout" kin init > "$3" 2>&1; then
fail "$1 failed" "$3"
fi
store="$(discovered_store "$2" "$layout" "$3")"
store="$(discovered_store "$2" "$4" "$3")"
if [ -z "$store" ]; then
fail "$1 returned success but no store serves $2" "$3"
elif [ ! -f "$store/manifest.json" ]; then
fail "$1 returned success but the store serving $2 holds no manifest: $store" "$3"
fi
if [ "$layout" = "in-tree" ]; then
if [ "$4" = "in-tree" ]; then
if [ ! -d "$2/.kin" ]; then
fail "$1 returned success without publishing $2/.kin" "$3"
elif [ -n "$store" ] && [ "$(basename "$store")" != ".kin" ]; then
Expand All @@ -670,12 +674,20 @@ jobs:
fi
require_no_stage_residue "$1" "$2" "$3"
}
require_refused() {
# Admit a fixture under the default (central) layout, or under
# `in-tree` when the fourth argument says so.
require_admitted() {
local layout="${4:-central}"
if ! fixture_kin "$2" "$layout" kin init > "$3" 2>&1; then
fail "$1 failed" "$3"
fi
require_published "$1" "$2" "$3" "$layout"
}
# What a refusal must leave behind: no store in the tree, none in the
# fixture's stores directory, none that discovery finds, and no stage.
require_nothing_published() {
local home
home="$(fixture_home "$2")"
if fixture_kin "$2" central kin init > "$3" 2>&1; then
fail "$1 unexpectedly succeeded" "$3"
fi
if [ -e "$2/.kin" ]; then
fail "$1 published authority at $2/.kin" "$3"
fi
Expand All @@ -686,7 +698,30 @@ jobs:
fail "$1 left a store serving $2" "$3"
fi
require_no_stage_residue "$1" "$2" "$3"
require_text "$1" "$NON_EMPTY_REFUSAL" "$3"
}
# Run `kin init` once on a populated directory with no Git history
# and hold the binary to the whole contract of the answer it gave.
# Success must publish exactly as the empty directory does and report
# the content as uncommitted work. Failure must publish nothing and
# give the refusal's own reason. Anything between the two fails.
#
# Taking either answer does not let a current binary pass as an older
# one. The refusal wording is gone from the source, so nothing built
# from it can print that reason, and
# scripts/assert-windows-init-contract.sh requires admission from
# every source build.
require_populated_contract() {
if fixture_kin "$2" central kin init > "$3" 2>&1; then
populated_outcome="admitted it and reported its content as uncommitted work"
echo "$1: kin init succeeded, so the admission contract applies."
require_published "$1" "$2" "$3" central
require_text "$1" "$POPULATED_UNCOMMITTED" "$3"
else
populated_outcome="refused it and published nothing, as a release built before populated admission does"
echo "$1: kin init failed, so the refusal contract of a release built before populated admission applies."
require_nothing_published "$1" "$2" "$3"
require_text "$1" "$NON_EMPTY_REFUSAL" "$3"
fi
}

git_boundary="$scratch/exact-git/repo"
Expand All @@ -704,19 +739,17 @@ jobs:
mkdir -p "$native_boundary"
require_admitted "Windows native-unborn bootstrap" "$native_boundary" "$native_log"

# A capability Windows now has must not become permission to derive
# authority from whatever happens to be lying in the directory.
populated_boundary="$scratch/native-populated/repo"
populated_log="$scratch/kin-init-native-populated.txt"
mkdir -p "$populated_boundary"
printf 'untracked\n' > "$populated_boundary/stray.txt"
require_refused "Windows non-empty native boundary" "$populated_boundary" "$populated_log"
require_populated_contract "Windows native-populated boundary" "$populated_boundary" "$populated_log"

if [ "$failures" -ne 0 ]; then
echo "::error::the installed Windows release violated its admission contract ($failures check(s) failed)"
exit 1
fi
echo "Installed Windows release admitted exact Git and native-empty repositories into central stores and exact Git into its own .kin, without stage residue, and refused the non-empty native boundary."
echo "Installed Windows release admitted exact Git and native-empty repositories into central stores and exact Git into its own .kin, without stage residue. Given a populated directory with no Git history, it $populated_outcome."

# Preserve a pre-repository Windows checkpoint in addition to the full
# repo/daemon/MCP proof below. It binds CLI provenance and proves that
Expand Down
41 changes: 27 additions & 14 deletions .github/workflows/release-rehearsal-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ jobs:
shell: bash
run: |
set -euo pipefail
POPULATED_UNCOMMITTED="Uncommitted work:"
NON_EMPTY_REFUSAL="requires an empty directory"

scratch="kin-windows-admission"
Expand Down Expand Up @@ -581,21 +582,17 @@ jobs:
git -c core.hooksPath= -c commit.gpgsign=false commit -qm probe
)
}
require_admitted() {
local layout="${4:-central}"
require_published() {
local home
local store
home="$(fixture_home "$2")"
if ! fixture_kin "$2" "$layout" kin init > "$3" 2>&1; then
fail "$1 failed" "$3"
fi
store="$(discovered_store "$2" "$layout" "$3")"
store="$(discovered_store "$2" "$4" "$3")"
if [ -z "$store" ]; then
fail "$1 returned success but no store serves $2" "$3"
elif [ ! -f "$store/manifest.json" ]; then
fail "$1 returned success but the store serving $2 holds no manifest: $store" "$3"
fi
if [ "$layout" = "in-tree" ]; then
if [ "$4" = "in-tree" ]; then
if [ ! -d "$2/.kin" ]; then
fail "$1 returned success without publishing $2/.kin" "$3"
elif [ -n "$store" ] && [ "$(basename "$store")" != ".kin" ]; then
Expand All @@ -613,12 +610,16 @@ jobs:
fi
require_no_stage_residue "$1" "$2" "$3"
}
require_refused() {
require_admitted() {
local layout="${4:-central}"
if ! fixture_kin "$2" "$layout" kin init > "$3" 2>&1; then
fail "$1 failed" "$3"
fi
require_published "$1" "$2" "$3" "$layout"
}
require_nothing_published() {
local home
home="$(fixture_home "$2")"
if fixture_kin "$2" central kin init > "$3" 2>&1; then
fail "$1 unexpectedly succeeded" "$3"
fi
if [ -e "$2/.kin" ]; then
fail "$1 published authority at $2/.kin" "$3"
fi
Expand All @@ -629,7 +630,19 @@ jobs:
fail "$1 left a store serving $2" "$3"
fi
require_no_stage_residue "$1" "$2" "$3"
require_text "$1" "$NON_EMPTY_REFUSAL" "$3"
}
require_populated_contract() {
if fixture_kin "$2" central kin init > "$3" 2>&1; then
populated_outcome="admitted it and reported its content as uncommitted work"
echo "$1: kin init succeeded, so the admission contract applies."
require_published "$1" "$2" "$3" central
require_text "$1" "$POPULATED_UNCOMMITTED" "$3"
else
populated_outcome="refused it and published nothing, as a release built before populated admission does"
echo "$1: kin init failed, so the refusal contract of a release built before populated admission applies."
require_nothing_published "$1" "$2" "$3"
require_text "$1" "$NON_EMPTY_REFUSAL" "$3"
fi
}

git_boundary="$scratch/exact-git/repo"
Expand All @@ -651,13 +664,13 @@ jobs:
populated_log="$scratch/kin-init-native-populated.txt"
mkdir -p "$populated_boundary"
printf 'untracked\n' > "$populated_boundary/stray.txt"
require_refused "Windows non-empty native boundary" "$populated_boundary" "$populated_log"
require_populated_contract "Windows native-populated boundary" "$populated_boundary" "$populated_log"

if [ "$failures" -ne 0 ]; then
echo "::error::the installed Windows release violated its admission contract ($failures check(s) failed)"
exit 1
fi
echo "Installed Windows release admitted exact Git and native-empty repositories into central stores and exact Git into its own .kin, without stage residue, and refused the non-empty native boundary."
echo "Installed Windows release admitted exact Git and native-empty repositories into central stores and exact Git into its own .kin, without stage residue. Given a populated directory with no Git history, it $populated_outcome."

- name: Windows repo-free provenance and setup proof
if: inputs.proof_mode == 'candidate-full' && (runner.os == 'Windows')
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/windows-vector-proof.yml
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,9 @@ jobs:
console.log(`feature_flags: ${meta.feature_flags.join(",")}`);
NODE

# Admission takes exact Git import or an empty native directory and
# refuses a populated non-Git one, so the fixture is a real Git worktree.
# The fixture is a real Git worktree with one commit, so admission
# imports the entities this proof embeds as recorded history rather than
# taking them in as uncommitted work.
- name: Seed a fixture repository and admit it
shell: bash
run: |
Expand Down
55 changes: 55 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,61 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- The local workspace (`kin ui`) is rebuilt so that each page does one job
and shows what Kin knows about the work. The sidebar lists every repository
on this machine, with a mark on the ones that hold uncommitted work or a
working agent, and the open repository unfolds into its three sections:
Work, Agents and Code.
- Work holds a change at each of its stages as three tabs: Uncommitted,
Branches and History. Uncommitted opens with a picture of the work: the entities it changed on one
side, joined to the entities that rely on them and did not change on the
other, each in the colour of what it asks of you. A larger change is also
listed in full, ordered by what needs your attention. The page names any
place where an agent's activity meets that work, and commits the work under
the same author resolution as `kin commit`.
- Review is a guided walk, one entity to a page, over uncommitted work, a
committed change, or one branch against another. Each page shows the
entity's source before and after, a picture of what relies on it and whether
each of those changed too, and the tests that reach it. You mark it as looking right or flag it
with a note, by button or by key. The last page gathers the flags to copy,
commits uncommitted work, or keeps how a committed change read to you. A
review is advisory: it stops and starts nothing. What you looked at is kept
on this machine and follows uncommitted work into the change it becomes.
- History lists a repository's changes, says for the newest what each left
behind (what relies on it and did not change, and whether a test reaches
it), and opens each one in the guided review. Branches creates, switches,
merges and compares branches, and settles a merge's conflicts entity by
entity, without a terminal.
- Code asks the repository by meaning or by name. An entity's page says what
a change to it might affect, then holds its Connections, Source, Members and
History as tabs; Connections is a flat picture of what relies on it and what
it relies on, in place of the repository map.
- Agents gives each coding agent a lane: what it has open, the entities it is
looking at, what it did last, and the whole timeline of what it asked Kin
for when opened. Where an agent's work meets your uncommitted work is said
above the lanes.
- The pages share one design in the system typeface, with light and dark
themes. The single-page review reader shares its colours.

### Added

- `kin ui` starts without a repository and opens Home, which says where things
stand on this machine: the work waiting on you, drawn as the same picture;
the agents working through Kin right now and what each last did; every
repository with its size, its languages and what is in motion in it; and
what was committed lately. One question can be put to every open repository
at once, and each answers from its own graph. Home lists repositories
without starting any of them, then opens the most recently changed few so
each can say what it holds. A repository registered after the page server
started opens without restarting it.
- Home adds a repository without a terminal: it looks at a place on this
machine and says what it holds, then converts a project, starts a new
repository, opens one Kin already holds, or clones one, and shows the
conversion's progress.
- Coding agents found on this machine are connected to Kin from the app.

## [0.8.6] - 2026-10-13

0.8.6 is the first release after 0.8.1. It ships everything recorded under
Expand Down
Loading
Loading