The tick — the project's heartbeat
A tick is a single, bounded act of stewardship that every agent performs at session start (and that autonomous sessions perform on a loop). Ticks are how a corpus-driven project stays alive without a human driving every step: we pump ticks at one subject slice at a time, and each tick either makes the design corpus more precise or surfaces the thing preventing that.
Taking a tick
Section titled “Taking a tick”- Brief, then work the queues in order. Run
tools/tick-brief.shfor the whole intake picture in one shot: recent commits, activity, project status, decision labels, the findings queue, and the stalest coverage rows. Then take the first queue that has work:- Harvest — a
decision-madeissue. Cameron already decided; converting his answer into law/spec motion is the highest value per tick. Convert, close, done. - Findings queue — a recorded surplus finding in the tick ledger. Verify it is still true (the code or corpus may have moved since it was recorded), then act on it.
- Fresh audit — only when both queues are empty. Pick the stalest slice from the ledger’s coverage table (or a slice the ledger has never seen). Fresh discovery is the fallback, not the default.
- Harvest — a
- For a fresh audit: read the corpus map and the chosen
coherent subject slice: its relevant
Type: law, owningType: spec, declared dependencies, and nearbyType: knowledgepages. Start from the spec’s checkedDesign:anchors; they identify the binding clauses the system claims to realize. A missing, misleading, or duplicate-owner reference is itself a contradiction. - Find one thing to act on — the highest-severity one you can see:
- a violation: the code does not do what the binding corpus says;
- a contradiction: current corpus pages disagree;
- a question: the corpus is ambiguous or silent where the code needs it to speak;
- a bug: the code disagrees with itself or with reality;
- an insecurity: something unsafe in code, tooling, or process.
- Act on it, per the table below. One act per tick — bounded beats exhaustive, because ticks repeat. Surplus findings you saw but did not act on are not dropped: record each as one line in the ledger’s findings queue. Discovery is the expensive phase of a tick; paid-for findings must not evaporate.
- Leave a trace: update the slice’s row in the coverage ledger — a clean verdict is a trace — plus the commit(s), the issue, or the spec marker. A tick that changed nothing and recorded nothing did not happen.
What each finding demands
Section titled “What each finding demands”| Finding | Action |
|---|---|
| Violation | Fix the code toward the owning law/spec page. If the code is right, amend that page deliberately with a defense. Never let them drift silently. |
| Contradiction | File a Tangled issue quoting both pages, use the issue body standard below, and label it decision-required. Do not silently pick a side unless one reading is obviously a typo. If it blocks work, add an [OPEN] marker to the owning binding page. |
| Question | If it is small and answerable within existing intent, make the owning page more precise with a defense. If directional or a taste call, file a decision-required issue and add an [OPEN] marker to the owning page. |
| Bug | Fix it, add a regression test, commit with a defense. |
| Insecurity | Fix or remove it. Never ship the insecure path because it was convenient. Defense in the commit. |
The defense rule
Section titled “The defense rule”Every commit that changes behavior carries a defense in its commit message: a short paragraph stating which corpus clause justifies the change — or, when the commit amends that clause, why the amendment is right. Format:
Defense: wiki/mechanics/detection.md specifies per-observer suspicion; thesingle global heat pool violated it. This implements the observer splitwithout changing the tuned pacing.No defense, no behavior change. The point is that the design corpus becomes much more precise over time: every change either cites the law or improves it.
Filing issues (Tangled CLI)
Section titled “Filing issues (Tangled CLI)”The CLI is tang (source at ~/code/tangled-cli, Cameron’s fork —
disconnected from the markbennett.ca upstream). The global binary is a
symlink to ~/code/tangled-cli/dist/index.js.
tang context # verify repo resolutiontang issue listtang issue create "Question: ..." -F body.mdtang label add issue <n> decision-required # waiting on Camerontang issue view 1tang issue edit 1 -F body.md # rewrite if an issue is not answerabletang label add issue <n> decision-made # Cameron answered; harvest next- Auth is one-time per machine and human-only:
tang auth login(browser OAuth). If commands fail with “Not authenticated”, stop and ask the user to log in rather than working around it. - Issue titles: prefix with the finding type —
Contradiction:,Question:,Violation:— so the issue list reads as the project’s open questions. The rest of the title is the decision itself (“four origins or five?”), not a topic label (“chargen thoughts”).
Issue body standard (binding)
Section titled “Issue body standard (binding)”Every Tangled issue filed for Cameron is a decision packet, not a status dump or agent diary. He must be able to open any issue and answer it in under two minutes without reading the surrounding session.
Required sections, in this order:
## Question— one concrete question. Prefer a numbered multiple-choice list (1./2./3.… plusSomething else (say what)). Never leave the ask buried in a paragraph of context.## Why this is open— short analysis: what the docs/code currently say, what conflict or gap forces a human call, and what is already decided (so he does not re-litigate settled ground). Quote file paths; keep it to a few sentences.## Options— 2–4 real alternatives with one honest trade-off line each (which pillar/clause it serves or strains). Tables are fine.## Recommendation— one marked pick and a one-line reason. Turns the issue into a yes/no override, not an essay question.## What your answer unlocks— the mechanical next step (which binding wiki page to amend, which ROADMAP item unblocks, when to close the issue).
Hard rejects (do not file, or rewrite before leaving):
- A body that is only narrative / session notes with no singular question.
- A question that cannot be answered without opening other files first.
- Multiple unrelated decisions packed into one issue (split them).
- Jargon-dense prose that restates the wiki instead of asking for a call.
If you find an existing open issue that fails this standard, rewrite it with
tang issue edit before doing other harvest work on it. An unanswerable
issue is process debt, same species as a stale [OPEN] marker.
Decision labels (binding)
Section titled “Decision labels (binding)”Two custom Tangled labels track whether an issue still needs Cameron:
| Label | Meaning | Who applies it |
|---|---|---|
decision-required |
Open ask waiting on Cameron. Body must already meet the issue standard above. | Agent, when filing or refreshing a human decision |
decision-made |
Cameron has answered (in the issue thread, chat, or decision history). Ready for harvest into law/spec/ROADMAP motion, then close. | Agent, as soon as the answer is recorded — or Cameron |
Rules:
- Every newly filed Question/Contradiction issue that needs a human call gets
decision-requiredin the same turn astang issue create. - The two labels are mutually exclusive: applying one removes the other
(
tang label adddoes this swap automatically). - Harvest prioritizes
decision-madefirst (convert + close), then unlabeled / stale open issues, and leavesdecision-requiredalone except to rewrite incomprehensible bodies. - Do not close a
decision-requiredissue just because it is old. Do not leave an answered issue ondecision-required— flip it todecision-made(or convert and close in the same harvest).
tang label defstang label list issue 1tang label add issue 1 decision-requiredtang label add issue 1 decision-made # also clears decision-requiredtang label remove issue 1 decision-madeTick etiquette
Section titled “Tick etiquette”-
Metered resources are not tick fuel. Anything that spends a shared, capped resource (API generation quotas, paid credits) is session work to do with Cameron present, not autonomous-tick work — unless the remaining capacity is known and generous. An autonomous tick that drains a shared quota blocks the human’s own use of it.
-
User-gated means quiet. When every open item waits on an action only the human can take (account access, billing, a browser login), say so once, lengthen the loop interval, and retry only the cheap checks. Do not convert “blocked” into invented work.
-
Highest severity first; insecurity and violations outrank questions.
-
Do not hoard acts: one per tick, then end the tick. Surplus findings go into the ledger’s findings queue as one-liners so the next tick (or the next agent) starts from them instead of rediscovering.
-
If a tick finds genuinely nothing, record the clean verdict in the coverage ledger, say so in one line, and stop — do not invent work. A clean row is durable value: it steers later ticks toward staler slices. Three quiet ticks in a row on stalest-first slices means the audited corpus and code agree; that is success, not failure.
-
Recurrence promotes to the gate. A mechanical finding class seen twice (a quoted code path that no longer exists, a stale constant, a broken structural reference) becomes a
tools/corpus_engine.pychecker instead of a third tick. Model attention is for semantic drift; the gate owns everything a script can verify. If implementing the checker exceeds the tick, queue it as a finding. -
Significant ticks get a line in
wiki/log/DEVLOG.md; routine ones are traced by their commits/issues alone.