Private preview · local-first on macOS

Your agent writes the change.
Struktly keeps the work accountable.

Give Struktly an outcome. It keeps a durable understanding of the system behind it — its architecture, rules, decisions, and unknowns. Then it structures the work, governs what may run, and connects the evidence to your decision about whether the result is right. Models are replaceable; that understanding is not.

Local desktop application · Git-native · Provider-independent · Private preview

  1. OracleWhat the system knows
  2. IntentWhat you want changed
  3. GraphWhat depends on what
  4. IntelligenceWho should take it, and why
  5. GovernWhat may run, and why
  6. EvidenceWhat actually changed
  7. AcceptWhat you choose to keep
  8. RememberWhat the accepted work taught
  1. UnderstandOracle · intent · graph
  2. RunChoose, govern, and observe the work
  3. DecideReview, accept, and carry it forward
A loop, not a pipeline: what you accept changes what Struktly understands, and that is where the next piece of work starts.

The product

Understand the system. Hold the work to it.

Running an agent is becoming ordinary. Keeping a durable account of what this system does, what was already decided, and what the change in front of you is answerable to — that is the part still worth having after the process stops.

01It understands your system

struktly/website

Oracle

What Struktly understands about this system.

Read after the latest change
UnderstandingProofsDecisionsUncertainty 2

What Struktly understands

Quoted from the repository; never promoted silently.

  • ArchitectureThe public site builds to static HTML.Source: README.md
  • Rule in forceAccess requests never grant release access.Approved · the website holds no GitHub admin credential
  • Product ruleRequests stay pending until a person approves them.Implemented · functions/api/access.js
  • Commandcorepack pnpm testDeclared by the repository

What it can prove

Sealed checks, not model confidence.

access-functionnode --test tests/*.test.jspassed

What it cannot say

The limit sits beside the claim.

  • Whether a person approved the request.
  • Whether GitHub access was granted.
The public page shows the product's shape and its disclosure discipline, not a customer repository, private prompt, provider credential, or proprietary decision rule.

02It holds the work accountable to it

ResultHarden access requestsKept
Held against
Requests stay pending until a person approves them.Product rule carried from the Oracle
Changes
Validation and storage preserve the pending approval boundary
Checks
corepack pnpm test passed · valid, invalid, storage, and honeypot paths covered
Unresolved
The site cannot say whether a person approved the request or GitHub granted access
Decision
Yours. Struktly assembled what supports it and did not make it
A green Check supports the product rule; it does not prove that approval happened. Struktly names that gap and leaves the verdict where it belongs.

How it works

From intent to a decision you can defend.

The ordinary path stays short. The structure appears when it helps you review, redirect, recover, or understand why something happened.

  1. 01

    Add a Workspace

    Point Struktly at a local Git repository. It reads what the repository declares, quotes its sources, and names what it could not derive.

  2. 02

    Describe the outcome

    Start a Chat or begin from a written Task. For larger work, Struktly proposes a dependency graph you can inspect before any Task is created.

  3. 03

    Approve the work

    A writable turn pins the exact input, Working copy, model, authority, and required Checks. External execution stays inside the Workspace allowance a person set.

  4. 04

    Accept with evidence

    Review Changes, Checks, decisions, attribution, and uncertainty. Keep the branch for normal Git work; the acceptance decision can inform the next turn.

Proposed graphHarden access requestsReview
FoundationPin request contract
WorkingValidate admission
WaitingProve recovery
Decision before creationNothing runs from a proposed graph.
A graph is shown only when work actually depends on other work. It is a plan to inspect, not a topology animation or an autonomous queue.

Intelligence

The executor is chosen, and the choice is explained.

Struktly tries the cheapest capable option first. External execution requires a person's Workspace allowance. Within that allowance, Struktly may choose an eligible executor automatically and records why.

Routing decisionRecorded at dispatch
  1. Gemma 4 E2BLocalruled out
    Capability
    can take writable work here
    Policy
    allowed
    Context
    the Task exceeds its context budget
  2. Claude CodeExternalchosen
    Capability
    can take writable work here
    Policy
    allowed for this Workspace
    Context
    the Task fits

Struktly used Claude Code because the local model had no context room for this Task, external execution was allowed here, and the work edits the repository.

The reason is composed when the decision is made, not reconstructed afterwards from what ran.

Evidence

Review the change without trusting the story.

Struktly sits where intent becomes a diff. It keeps the evidence that a downstream review tool receives too late: turn boundaries, authority, decisions, checks, and the gaps in what was observed.

Every changed line names its origin

Each changed line in the working copy names the turn that wrote it, says that no turn did, or says unknown. That is a statement about where a line came from — not about which instruction caused it, and not that it is correct.

internal/auth/limit.go

  • func (l *Limiter) Allow(key string) bool {turn 7
  • l.mu.Lock()turn 7
  • defer l.mu.Unlock()turn 9
  • return l.bucket(key).take()no turn
  • }unknown

Checks, and what they returned

Commands run against the working copy and keep their result: pending, running, passed, failed, skipped, interrupted. A passing command is evidence, not proof that the change is right.

  • go test ./...passed
  • make integrationskipped
  • make benchinterrupted

Trust names the boundary and its gaps

Struktly separates what it enforced, what it observed, and what stayed outside the Record. It never turns “we saw an event” into “we prevented the action.”

Enforced

Writable turns pin exact input and one writer. On macOS, provider processes can use a Seatbelt write boundary and controlled egress; locked mode refuses the spawn if that boundary cannot be applied.

Observed, not enforced

Lifecycle and tool activity are recorded only where the runtime exposes them. A provider CLI's internal commands, prompts, and network exchanges remain inside its own process.

Outside the Record

Terminal content, ephemeral streaming output, and Chat content are not persisted. Those gaps are written into the Record itself.

Current preview boundary: macOS. Provider CLI reads remain broader than writes; local services may be admitted for a declared Check and that exception is recorded. No Linux confinement claim is made.

Passing Checks, a sealed Record, or an agent review cannot accept the result. Struktly shows what remains unresolved; you decide what to keep.

Where the work runs

The model can change. The custody stays put.

A Chat, its Working copy, decisions, and evidence belong to Struktly. The model that takes the next turn can be local, a CLI already signed in on this Mac, or an endpoint you connect.

Embedded runtime

A model that runs on your machine

The llama.cpp server is embedded in the signed application. The weights are not: a catalogue pinned in the release names a small set, and the one you pick is downloaded once — resumable, cancellable, removable — and verified by size, SHA-256, and format before it runs. Hugging Face and a file already on disk import on the same terms.

After that it is not a chat box. The model reads files, edits them, and runs the Task’s declared commands through tools Struktly owns and performs itself.

  • Once the model is on disk, a turn needs no account, no key and no network
  • Its shell runs inside the Working copy, in a sandbox with no network at all
  • A model that cannot call tools natively is constrained to a JSON action grammar instead, and still edits
  • Pinned in the release, or imported from Hugging Face or a file on disk

A small local model is not a large one. Work is offered only after that exact model has proved file editing and shell use on this machine, and when a Task will not fit, the routing ladder says so and climbs rather than letting it flail. Capability is measured here, never inferred from the model name.

provider CLI

The tools you already use

Claude Code and Codex run from the executables already signed in on this Mac. Struktly owns the work around the process; the provider owns what happens inside it.

  • Your existing subscription and login
  • macOS write and egress boundary where supported
  • A terminal you drive remains first-class
connected endpoint

An OpenAI-shaped endpoint

Add a base URL, model, and—only when needed—a key. Local servers and hosted providers use the same explicit connection boundary.

  • Keys stay in the macOS keychain
  • Presets are conveniences, not an allowlist
  • External stdio adapters remain an advanced option

FAQ

Common questions

What the product is, what it records, and what it deliberately does not claim.

What is Struktly?

Struktly is a local desktop workspace for repository-aware AI work. A Git repository becomes a Workspace. You can open a Chat directly or start from a written Task; writable turns use an isolated Git Working copy, and the understanding, decisions, Changes, Checks, and Record remain connected to the work.

Is Struktly a coding agent?

No. Struktly is the local layer around the work. It understands the repository, prepares and governs the turn, keeps the Working copy and evidence, and presents the acceptance decision. A local model or a connected provider can write code, but Struktly does not replace Git, your editor, your terminal, or human review.

What does the Oracle know?

The Oracle presents what Struktly has read and what a person has approved: repository structure, declared commands, rules in force, proofs, carried decisions, and uncertainty. A statement remains tied to its source. Reading a sentence from a file does not make that sentence correct, current, or approved.

Can the bundled local model edit code?

Yes, after that exact model passes an on-device probe for Struktly's file and command tools. A model that has not passed is offered for Chat only. Local Work stays inside the Task's Working copy, uses declared or detected commands, records each tool result, and runs under the current macOS confinement boundary.

Which external models can take a turn?

Claude Code and Codex can run from executables already signed in on this Mac. OpenAI-compatible local or hosted endpoints can be connected with a base URL, model, and optional key. Advanced external stdio adapters are supported too. External execution requires a person's Workspace allowance. Within that allowance, Struktly may choose an eligible executor automatically and records why.

Where does the work live, and what leaves the machine?

Chats, Working copies, Records, and the database live on this machine. Connected-provider keys live in the macOS keychain. A local turn can stay local; an external turn sends the approved request to an eligible provider only within a person's Workspace allowance. A provider CLI may make its own requests, which Struktly does not pretend to inspect.

Does it need GitHub, or a particular Git host?

No. Struktly works from a local Git repository and prepares ordinary Git worktrees for writable Tasks. Keeping work does not push, open a pull request, or merge it; publication remains part of your normal Git workflow.

What does the Record not capture?

The Record says that operations inside provider and terminal processes may remain opaque, terminal content and ephemeral streaming output are not persisted, and Chat content is not copied into provenance. Additional gaps are added when evidence, attribution, runtime capability, or Git state is missing. Observed is not enforced, and passed is not the same as accepted.

What does the boundary around a provider CLI actually deny?

On supported macOS hosts, Struktly can deny writes outside the Task's Working copy and required runtime state, and force provider egress through a controlled local path. Reads remain broader than writes, provider internals are not intercepted, and a terminal you drive is not wrapped as an agent spawn. Locked mode refuses a spawn when the promised boundary cannot be applied.

Which platforms does the preview run on?

The private preview is a macOS build for Apple silicon, and it is not notarized yet. Linux is not a porting problem — the daemon is Go, the desktop is Tauri, and the release pipeline already builds unsigned Linux bundles. It is a boundary problem: the write and egress confinement around a provider process is macOS Seatbelt, so on Linux Struktly reports that it cannot confine the spawn, and locked mode refuses to start one rather than implying a boundary it does not have. The preview is handed out for macOS until Linux has an answer of its own; Linux requests sit on the waitlist.

How do I get the preview?

Request access with the form below. Approved requests receive read-only access to the private releases repository. The open-source repository-context CLI is separate and remains available without desktop preview access.

Private preview

Try it on a repository you already know.

Apple silicon macOS builds are available by request. Linux requests remain on the waitlist — the blocker is the confinement boundary, not the build.

Approved requests receive read-only access to the private GitHub releases repository. Requests stay pending until a person approves them.

Fridthjof Labs uses these details only to review and manage preview access. Read the privacy notice.

Direction — not in the product yet

The next decision should be able to cite the last one.

Today a routing decision is defended by capability and policy: this agent can do the work here, and you allowed it. That is defensible. It is not yet evidenced.

Every accepted or rejected result already carries durable truth — which executor took it, what was tried first, what the Checks said, how long it ran, whether a person had to step in, and whether the work was kept. Struktly does not record that as history, so it cannot yet answer the question a person actually has: how has this kind of work gone before?

The intent is to record it, make it readable, and only then let routing cite it — advisory first, and never a number the system cannot show its working for.

Nothing above this section depends on it. Everything else on this page is in the private preview today.