Skip to content

feat: let a task name a task definition, and take its checks and its tools - #74

Merged
sstriker merged 5 commits into
mainfrom
feat/task-definitions
Nov 12, 2026
Merged

sstriker merged 5 commits into
mainfrom
feat/task-definitions

Conversation

@sstriker

@sstriker sstriker commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

This is package 3 of PLAN.md, first part.

The paper makes a task definition the record for one kind of work (§8 Admission and Matching, §10). A task names one. The definition gives the acceptance checks of the task, and the tools that its holder can use. The code had no such record.

What changes

  • A task definition is a new kind of artifact in the platform domain: a fenced block platform task <name>, in TOML. It has a purpose, tools, a scope, acceptance checks, outputs and an autonomy level.
  • A definition is in force when its entry is active and a person verified it. The newer of two such entries is in force. The version of a definition is the id of its entry.
  • A task has a definition and acceptance. A task that is filed with a definition records <name>@<entry>. It takes the checks of the definition if it gives none. It requires the tools of the definition. It gets the classification of the entry, if that is higher.
  • A task cannot name a definition that is not in force. A session gets the same refusal for a definition that it cannot read.
  • A session that holds a task of a definition can call only the tools that the definition declares. The check uses the entry that the task named. When that entry is not in force, the session can call no tool.
  • A task that a session files while it holds a task gets the definition and the checks of that task. This applies to a subagent task, its continuation and a retry.
  • A session has the tools that the grants give it among its capabilities, so it can claim a task that requires them.
  • [gates] require_definition = true in the grants makes a definition and acceptance checks necessary for admission by triage. It is off by default, because the tasks that the system files name no definition yet. The owner can admit such a task.
  • create_task and amem task create take the definition and the checks. create_task gives not_admitted_because. amem work puts the definition and the checks in the prompt.
  • The ledger keeps the two fields in a new extra column, as JSON, on the two backends.
  • Act 7 of the demo proposes, verifies and uses a definition (step 7.5).
  • README.md and PLAN.md say what packages 2 and 3 built, and what is open. local/README.md has a section on task definitions.

Not in this change

No suite gates a version of a definition. The data scope is not enforced. The autonomy level has no effect. An erasure of the entry of a definition does not remove the checks that tasks took from it.

Checks

make check passed with 967 tests on 0a19cf9. make corpus-check passed. The ledger tests ran on SQLite and on the embedded PostgreSQL.

Adversarial pass

The pass ran on a9513a4. It confirmed seven findings, and f64dacf corrects them:

  1. A task that a session filed while it held a defined task had no definition, and its holder could call each tool.
  2. A session with low handling could take the checks of a definition that it could not read. A refusal quoted the text of an entry.
  3. The version was a count that changed. The tool check used only the name.
  4. The tool check passed when it could not read the held task.
  5. A definition that declared a tool made a task that amem work did not claim.
  6. With require_definition, the owner could not admit a task that the system filed.
  7. Four changes to the code left all tests green. Each now has a test.

The first form of the PostgreSQL catalog check gave the schema name with its quotes, and never matched. A test of an old domain shape found it before the push.

A second pass ran on f64dacf. It confirmed seven findings, and 0a19cf9 corrects them:

  1. f64dacf let each session admit a task past the definition gate. Only the owner now passes it.
  2. The held task of a session was set one time. A launcher that works one task after the other kept the definition of the first task.
  3. A subagent task had the definition but no requirements.
  4. A retry kept the entry that the first attempt named, also after that entry left force. A retry now takes the definition by its name.
  5. The read of the entry of a definition counted as a get, and changed the default depth of a later recall.
  6. A session that can read the entry got "not in force" for a block that does not parse.
  7. Five changes to the code left all tests green. Each now has a test.

The pass confirmed that a session gets the same refusal for a definition that it cannot read and for one that does not exist.

Open

  • No pass read 0a19cf9.
  • When the entry of a definition leaves force, the tasks that named it cannot continue. local/README.md says what the owner does then.
  • capabilities() gives tool:<tap> to each session of the root. It does not ask if the session could handle the results of that tool. The pass gave this from reasoning only.
  • A fan-out under a definition that is no longer in force fails with the refusal for that definition.

Posted by Claude on behalf of @sstriker

🤖 Generated with Claude Code

sstriker and others added 5 commits November 12, 2026 07:31
…tools

The paper makes a task definition the record for one kind of work (§8
Matching, §10). A task names one. The definition gives the acceptance checks,
and the tools that a claimant can use. The code had no such record.

- A task definition is a new kind of artifact in the platform domain:
  `platform task <name>`, in TOML. It has a purpose, tools, a scope,
  acceptance checks, outputs and an autonomy level.
- A definition is in force when its entry is active and verified. Its version
  is its place among the verified definitions of that name.
- A task has a `definition` and `acceptance`. When a task is filed with a
  definition, it records `<name>@<version>`. It takes the checks of the
  definition if it gives none. It requires the tools of the definition.
- A task cannot name a definition that is not in force.
- A session that holds a task of a definition can call only the tools that the
  definition declares.
- `[gates] require_definition = true` in the grants makes a definition and
  acceptance checks necessary for admission. It is off by default, because the
  tasks that the system files for itself name no definition yet.
- `create_task` and `amem task create` take the definition and the checks.
  `amem work` puts them in the prompt.
- The ledger keeps the two fields in a new `extra` column, as JSON.
- Act 7 of the demo proposes, verifies and uses a definition.

Not in this change: the autonomy level has no effect, no suite gates a
version of a definition, and the scope is not enforced.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
The pass ran on a9513a4 and confirmed seven findings.

- A task that a session filed while it held a defined task had no
  definition. A session that held such a task could call each tool. A task
  filed under a held task, a subagent task, its continuation and a retry now
  get the definition and the checks of that task.
- A session with low handling could take the checks of a definition that it
  could not read. The refusal for a block that did not parse quoted the text
  of the entry. The memory server now reads the entry of the definition as
  each entry is read. It gives one refusal for a definition that the session
  cannot read and for one that does not exist. The task gets the
  classification of the entry. No refusal quotes the text of the block.
- The version was a count of verified entries. It changed when an entry left
  the verified tier, and the tool check used only the name. The version is now
  the id of the entry. The tool check uses the definition that the task named.
  When that entry is not in force, the session can call no tool.
- The tool check passed when it could not read the held task. It now gives the
  error.
- A definition that declared a tool made a task that `amem work` did not
  claim, because that session had no manifest. A session now has the tools
  that the grants give it among its capabilities. A tool that is not
  `tool:<name>` makes the definition unreadable.
- With `require_definition`, the owner could not admit a task that the system
  filed. The owner can now admit a task with no definition. Nobody can admit a
  task whose definition is no longer in force.
- Four changes to the code left all tests green. Each now has a test: the
  tool path refuses, the newer of two definitions is in force,
  `not_admitted_because` has the reason, and a ledger file with no `extra`
  column gets one.

On PostgreSQL, a connect asks the catalog before it adds the column. The first
form of that check gave the schema name with its quotes, and never matched.
A test of an old domain shape found it.

README.md and PLAN.md now say what packages 2 and 3 built, and what is open.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
The pass ran on f64dacf and confirmed seven findings.

- f64dacf let each session admit a task past the definition gate, where the
  intent was the owner. A session thus admitted its own task with no
  definition. Only the owner now passes that gate.
- The held task of a session was set one time. A launcher that works one task
  after the other kept the definition of the first task. The held task is now
  the latest that the launcher set.
- A subagent task had the definition but no requirements, so a session
  without the tools of the definition could claim it. A subagent task is now
  bound as each filing is, and requires those tools.
- A retry kept the entry that the first attempt named, also after that entry
  left force. A retry now takes the definition by its name, as it is in force.
- The read of the entry of a definition counted as a `get`. Two such filings
  changed the default depth of a recall. The memory server now looks at the
  entry under the read filter and raises the label of the session, and does
  no more.
- A session that can read the entry got "not in force" for a block that does
  not parse. It now gets the refusal that says so.
- Five changes to the code left all tests green. Each now has a test: a
  retry, `claim_next` with a granted tool, the own checks of a parent in a
  child and in a filing under a held task, and the admit of a task whose
  definition is gone, which no longer depends on a condition.

`admit_per_policy` no longer asks if the definition is gone. A filing binds
the definition first, so that case does not occur there.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
@sstriker
sstriker marked this pull request as ready for review November 12, 2026 07:41
Copilot AI balanced review requested due to automatic review settings November 12, 2026 07:41

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

@sstriker
sstriker merged commit f5d9eaa into main Nov 12, 2026
10 checks passed
@sstriker
sstriker deleted the feat/task-definitions branch November 12, 2026 11:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants