splitgate

package
v0.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 4, 2026 License: Apache-2.0 Imports: 2 Imported by: 0

Documentation

Overview

Package splitgate is the enumeration evidence gate: does a piece of work name enough independent items for dividing it to beat one worker doing them in order?

AND SINCE 2026-09-02 IT ASKS ONLY WHEN SOMEBODY ASKS IT TO. The gate shipped armed under a six-item floor, and a designed experiment — four planner arms against four readings of this gate, 273 judged draws on the plan door — put the planner with the gate OFF on the front and left every armed reading behind it (docs/design/plan-gate-doe/REPORT.md). So an unpinned binary keeps every division the planner drew, and the counting below decides only where somebody has pinned `CODEAF_SPLITGATE=1` or `judgment`. modes.go holds the pin and the reasoning; everything else in this file is the counting itself, which the experiment did not change and which arming still reads (internal/session's enumeratesWidth).

IT IS ONE ANSWER, ASKED IN THREE PLACES. The gate was written for the resident's planner and its leaves (cmd/codeaf/cooperative.go) and measured against the swarm bench corpus, where it reproduced the empirically best arm's decision on every task in the table: twelve image files and eight endpoints divided, four modules and three bugs did not. The v3 session engine now asks the same question of a task's own work (internal/session's task_divide.go), and a second implementation of it would be a second answer — the fault CLAUDE.md's one-source-of-truth law names, applied to a decision instead of to a number. So the counting lives here, with no dependency on either product, and both call it.

IT COSTS NOTHING. There is no model call in this package and there never should be: the gate is asked on every division request and on every task admission, and a gate that spent money to say no would be more expensive than the division it refused.

AND IT FAILS OPEN ON WORDS IT HAS NEVER MET. The first counter carried a list of eighteen item-nouns and counted a number only beside one of them, which read "34 person-rows" and "34 research targets" as nothing at all — a live OSINT task was twice told its thirty-four people were zero items, on the honest evidence, because nobody doing that work writes "files". A list of the things people have piles of is open-ended and always behind the next domain. What is CLOSED is the opposite list: the measures, budgets and repetitions whose number sizes one thing rather than counting many — words, seconds, retries, steps. So the gate now counts a number beside any plural word that is not a measure, and an unfamiliar domain errs toward counting, with the paid reviewer behind the gate as the check on what it lets through (task_divide.go reads every division before admitting it).

Index

Constants

View Source
const Floor = 6

Floor is the smallest item count at which division has ever paid in the bench corpus: twelve image files won, four modules and three bugs lost.

View Source
const SizeOversized = "oversized"

SizeOversized is the planner's word for work that is still too big to be one sitting (internal/plan's SizeOversized, spelled here rather than imported).

Variables

This section is empty.

Functions

func Armed

func Armed() bool

Armed reports whether the gate has the last word.

IT IS OFF UNLESS SOMEBODY PINNED IT ON, which is the opposite of what this switch meant until 2026-09-02. The gate shipped armed and rolled back with the literal "0"; a designed experiment then measured four planner arms against four readings of it and the front it drew is the planner with this gate having no say (docs/design/plan-gate-doe/REPORT.md). So the arming moved into the pin: `1` for the count below, `judgment` for the plan's own sizing, and everything else — an unset pin included — for the gate keeping quiet. modes.go's Mode is where that is read, and this is one bit of it.

It stays an environment pin and not a settings row for the reason it always was one (internal/config's settings.go): it picks which decomposition doctrine the binary runs, which is not something the product has an opinion about, and it disappears when nobody has a reason to reach for it.

func Items

func Items(text string) int

Items returns the largest explicit count of independent items a text names.

A number counts when a countable word FOLLOWS it within three tokens — "34 person-rows", "12 image files", "9 endpoints" — because that is the order English enumerates a pile in. A word BEFORE a number counts only across a colon ("bugs: 3", "errors: 12"): in running prose the word before a number is a verb or a preposition ("holds 34", "under 250"), and reading "covers 250 words" off its verb would resurrect exactly the parameter-counting this gate exists to refuse. Bare numerals are never items: "limit=100" and "250 words" name a parameter and a measure, and a gate that read them as items would divide work that never should be.

func WorthIt

func WorthIt(evidence string) bool

WorthIt reports whether a text enumerates enough independent items for a division to beat one worker doing them in sequence.

Types

type Decision

type Decision struct {
	// Keep is the answer: true leaves the division standing.
	Keep bool

	// Items is what the brief counted, whether or not the count decided. It is
	// what a fold is explained by, and it is filled in on a keep as well so a
	// run's log can show what the count was when nothing was made of it.
	Items int
}

Decision is what the gate answers and what a caller writes down about it.

func Judge

func Judge(text string, leaves []Leaf) Decision

Judge answers the one question this package exists for: does this division stand? It is asked at the plan door with the planned leaves and at a running leaf's own request with none, and the mode is read once, here.

Leaves may be nil, and nil is not "a graph with no parts" — it is "nobody can tell me about the parts", which is the honest situation at a leaf's own division request, where all that exists is the evidence it wrote down. A caller holding a graph passes its work leaves; a caller holding only text passes nil and gets the count.

type GateMode

type GateMode string

GateMode is which reading of "is this division real" the binary is running. It is a string rather than an integer because the pin is read by people typing it in front of a command, and `CODEAF_SPLITGATE=judgment` says what it is doing where `CODEAF_SPLITGATE=3` would not.

const (
	// ModeOff is the gate having no say: a division stands as it was drawn.
	// It is what an unset pin selects — and what `0`, the rollback switch this
	// gate has always carried, still selects for anybody who spells it out.
	ModeOff GateMode = "0"

	// ModeCount is the gate as it shipped until 2026-09-02: [Items] over the
	// brief against [Floor]. It is what `1` selects, and it is still the right
	// reading for a run that wants a floor under the divisions it pays for.
	ModeCount GateMode = "1"

	// ModeJudgment is #418's other repair — stop reading the brief. The planner
	// has already sized every node and drawn the edges between them, so the
	// gate asks that instead: a division whose work leaves are each a sitting
	// and which owe each other nothing is a real division whatever the brief
	// counted.
	//
	// IT ONLY EVER ADDS KEEPS TO THE COUNT. When the plan's sizing does not say
	// yes — a leaf with no size, a leaf still oversized, or any edge between two
	// leaves — the count decides, exactly as in [ModeCount]. So this pin is the
	// count with a second way to say yes, which is what let the experiment read
	// it as one factor against the count rather than as a different gate.
	ModeJudgment GateMode = "judgment"
)

func Mode

func Mode() GateMode

Mode reports which reading this process is running.

AN UNRECOGNISED PIN READS AS OFF, WHICH IS THE DEFAULT, and that is a deliberate reversal. While the gate was armed by default an unreadable pin had to leave a run on the shipped gate, because the danger was a typo silently moving somebody onto an experimental arm. Now the danger runs the other way: the measured behaviour is the gate having no say, and a typo (`CODEAF_SPLITGATE=on`, `CODEAF_SPLITGATE=true`, `CODEAF_SPLITGATE=lanes` from the experiment that has since ended) must not quietly put a floor back under somebody's divisions. So the two words that arm it are exact, and everything else — including nothing at all — is off.

type Leaf

type Leaf struct {
	// ID is the leaf's identity in its own graph, which is what the other
	// leaves' Needs are written in terms of.
	ID int

	// Size is the planner's sizing word — "atomic", "borderline", "oversized" —
	// or empty where nothing sized this node. Empty is a different fact from
	// oversized and the gate treats it as one: unsized means the plan has no
	// opinion, and an opinion is what [ModeJudgment] came for.
	Size string

	// Needs are the IDs this leaf waits on. They may name nodes that are not
	// leaves at all, which is why independence is asked only about the pairs
	// inside the set handed over.
	Needs []int
}

Leaf is the whole of what this gate needs to know about one planned work node: how big the planner made it and what it waits on.

It is a plain struct and not internal/plan's own node because this package has no dependency on either product that asks it, and acquiring one to read two fields would put the counting behind the planner's import graph — the same reason the counting lives here at all.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL