Metadata
| Status | done |
|---|---|
| Assigned | agent-2372 |
| Agent identity | 3184716484e6f0ea08bb13539daf07686ee79d440505f1fdf2de0357707034c3 |
| Model | claude:opus |
| Created | 2026-05-04T17:36:48.071085263+00:00 |
| Started | 2026-05-04T18:37:36.473583249+00:00 |
| Completed | 2026-05-04T18:43:25.523935378+00:00 |
| Tags | agency,sync,research, eval-scheduled |
| Eval score | 0.89 |
| └ blocking impact | 0.93 |
| └ completeness | 0.96 |
| └ coordination overhead | 0.92 |
| └ correctness | 0.90 |
| └ downstream usability | 0.94 |
| └ efficiency | 0.90 |
| └ intent fidelity | 0.84 |
| └ style adherence | 0.91 |
Description
Description
Audit the field-level delta between workgraph's primitive types (RoleComponent, DesiredOutcome, TradeoffConfig in src/agency/types.rs:184-261) and agentbureau/agency v1.2.4's primitive schema (per https://github.com/agentbureau/agency/blob/main/specification.md). Produce a precise field-by-field diff and a concrete fix proposal.
Specific things to investigate
- Workgraph primitives lack:
quality(0–100),domain_specificity(0–100),domain(taxonomy: software/research/writing/analysis/legal/strategy/science/management),scope(task | meta:assigner | meta:evaluator | meta:evolver | meta:agent_creator),origin_instance_id,parent_content_hash(legacy single-parent ref). - Workgraph primitives carry that agency does not:
ComponentCategory(translated/enhanced/novel),ContentRef(Name|File|Url|Inline),success_criteria(DesiredOutcome),acceptable_tradeoffs/unacceptable_tradeoffs(TradeoffConfig),requires_human_oversight,AccessControl,PerformanceRecord,staleness_flags,domain_tags,metadata,former_agents,former_deployments. - Lineage shape: agency v1.2.4 spec uses parent_ids (JSON list), generation, created_by enum {human, import, evolver, agent_creator}, reframing_potential. Workgraph (
src/agency/types.rs:124-149) has parent_ids list + generation + created_by (freeform string) + created_at — close butcreated_byis not enumerated. - Decide: which of wg's extensions are intentional supersets (keep) vs accidental drift (rename or align)?
Deliverable
wg log entry on this task with:
- Per-type diff table (fields wg has, fields agency has, fields both share)
- Fix proposal: which fields wg should ADD as additive serde-optional fields, which to RENAME for compat, which to KEEP as documented superset
- Hash-input implications (defer to research-agency-hash-compat for the deep dive)
- Cited line ranges in
src/agency/types.rsand the agency specification.md
Validation
- Per-primitive-type diff table written
- Concrete add/rename/keep recommendation per missing field
- Cites file:line in src/agency/types.rs for each wg field
- Cites the matching agency specification section for each agency field
- Identifies which fields are required for federation hash compat vs purely metadata
Depends on
Required by
- (none)
Log
- 2026-05-04T17:36:48.045206148+00:00 Task paused
- 2026-05-04T18:36:22.791579564+00:00 Task published
- 2026-05-04T18:37:36.473588599+00:00 Spawned by coordinator --executor claude --model opus
- 2026-05-04T18:37:48.106822618+00:00 Starting field-level delta audit between workgraph primitives (src/agency/types.rs) and agentbureau/agency v1.2.4 spec
- 2026-05-04T18:42:13.555196112+00:00 === RESEARCH: agency schema delta — primitive fields === Audit of field-level delta between workgraph's primitive types (`src/agency/types.rs`) and agentbureau/agency v1.2.4's primitive schema (per `/home/erik/agency/specification.md` v1.2.3 + v1.2.4 lineage additions documented in design-agency-sync §A.1). Reference points: - WG types: src/agency/types.rs (lines cited inline) - WG hash inputs: src/agency/hash.rs:14-112 - Agency spec: /home/erik/agency/specification.md (v1.2.3 in local clone; v1.2.4 lineage additions from design-agency-sync §A.1) - Agency starter CSV columns: specification.md:449 (v1.2.3 = 9 cols; v1.2.4 adds parent_ids, generation, created_by → 12 cols per design-agency-sync §A.1) Vocab note: agency calls it "trade-off configuration" / "trade_off_config"; wg calls it `TradeoffConfig`. Same primitive, different orthography. No rename needed since they hash by content not by struct name. --------------------------------------------------------------------------- ## A. Common (shared by all three primitive types) --------------------------------------------------------------------------- These fields are shared by RoleComponent (rs:184-203), DesiredOutcome (rs:209-230), and TradeoffConfig (rs:240-261). Diff once, applies thrice. | Field | wg has? | agency has? | wg cite | agency cite | verdict | |-----------------------|----------------------|-------------------|-------------------------------|-----------------------------------|---------| | id (content_hash) | YES `pub id: String` | YES content_hash | types.rs:185,210,241 | spec.md:33-43 ("content_hash is THE primary key") | KEEP — same concept, different spelling. wg uses field name `id`, agency uses `content_hash` | | name | YES | YES | types.rs:186,211,242 | spec.md:449 (CSV col) | KEEP — identical | | description | YES | YES | types.rs:187,212,243 | spec.md:43,449 | KEEP — load-bearing for hash on both sides | | quality (0–100 int) | NO | YES | — | spec.md:43,449,705 | **ADD** — additive serde-optional `Option<u8>`. Required to round-trip starter CSV. NOT a hash input on either side | | domain_specificity | NO | YES (0–100 int) | — | spec.md:449,705 | **ADD** — additive serde-optional `Option<u8>` | | domain | NO | YES (taxonomy) | — | spec.md:449,705 | **ADD** — additive serde-optional `Option<String>` constrained to {software, research, writing, analysis, legal, strategy, science, management} (per design-agency-sync §A.1). Consider an enum | | scope | NO | YES (v1.2.3 enum) | — | spec.md:45-49,727 | **ADD** — additive serde-optional enum `Option<Scope>` where `Scope ∈ {task, meta:assigner, meta:evaluator, meta:evolver, meta:agent_creator}`. Default `task`. Wg currently encodes scope via task-id prefix (`.evaluate-*`, `.assign-*`, etc.) — orthogonal to the primitive scope; both can coexist (see research-agency-scope-rules) | | origin_instance_id | NO | YES (UUID v7) | — | spec.md:449,705 | **ADD** — additive serde-optional `Option<String>`. Identifies the agency instance that minted the primitive. Useful for federation provenance | | parent_content_hash | NO | YES (legacy) | — | spec.md:449,463 | **ADD** — additive serde-optional `Option<String>`. Single-parent legacy ref kept by agency for round-trip; wg's `lineage.parent_ids` (a list) is the modern replacement. Treat as a *deprecated mirror* of `lineage.parent_ids[0]` for CSV export only | | permission_block | NO | YES (13-char) | — | spec.md:705 | **ADD-LATER** — agency stores it but it's not in the starter CSV. Defer to impl-agency-integration; not needed for federation hash compat | | override_capability | NO | YES | — | spec.md:705 | **ADD-LATER** — same as above; agency-internal column, not in CSV | | performance | YES `PerformanceRecord` | implicit (via primitive_performance table) | types.rs:115-121,190,215,248 | (table, not on primitive) | KEEP — wg superset. Agency stores cascaded performance in a separate table; wg keeps it inline on the primitive YAML. No conflict — wg's `performance` block stays when round-tripping CSV (CSV has no perf data) | | lineage | YES `Lineage` | YES (4 sub-fields) | types.rs:124-149,192,217,250 | spec.md:705 + design §A.1 | RENAME — see §B below | | access_control | YES | NO | types.rs:56-69,194,219,251 | — | KEEP (wg superset). Agency uses ed25519 + JWT scopes for federation; wg's per-primitive `AccessControl{owner, policy ∈ {private,shared,open}}` (rs:47-69) is finer-grained. Document as wg-only | | domain_tags | YES `Vec<String>` | NO | types.rs:196,222,253 | — | KEEP — wg superset; multi-tag complement to agency's single `domain` field. Both can coexist | | metadata | YES `HashMap<...>` | NO | types.rs:198,224,255 | — | KEEP — wg superset, free-form escape hatch | | former_agents | YES `Vec<String>` | NO | types.rs:200,227,258 | — | KEEP — wg superset, evolutionary bookkeeping | | former_deployments | YES `Vec<DeploymentRef>` | NO | types.rs:201,228,259 | — | KEEP — wg superset | --------------------------------------------------------------------------- ## B. Lineage block (struct shared across all three primitives) --------------------------------------------------------------------------- WG `Lineage` (types.rs:124-149) vs agency v1.2.4 lineage: | Field | wg has? | agency has? | verdict | |-------------------|--------------------------------------|---------------------------------------------|---------| | parent_ids | YES `Vec<String>` (rs:127) | YES (JSON list of content hashes) | KEEP — same shape | | generation | YES `u32` (rs:129) | YES | KEEP — same shape | | created_by | YES `String` FREEFORM (rs:131) | YES enum `{human, import, evolver, agent_creator}` | **RENAME-OR-CONSTRAIN** — see below | | created_at | YES `DateTime<Utc>` (rs:133) | NO (agency uses table-level timestamps) | KEEP — wg superset | | reframing_potential | NO | YES (v1.2.4 new — design §A.1) | **ADD** — additive serde-optional `Option<f64>` | `created_by` resolution: wg currently emits freeform values like `"human"`, `"evolver-{run_id}"` (types.rs:157, 171). Agency requires an exact enum value. Three options: 1. **Strict enum** — change `created_by` to `enum CreatedBy { Human, Import, Evolver, AgentCreator }`. Loses `run_id` provenance from `evolver-{run_id}`. 2. **Tagged enum** — `enum CreatedBy { Human, Import, Evolver{run_id: String}, AgentCreator{run_id: String} }`, serialize as plain string `"evolver"` for federation (drop run_id) and keep run_id in metadata. 3. **Strict enum + side channel** — adopt agency's enum and migrate existing `evolver-{run_id}` → `evolver`, parking `run_id` in `metadata["evolver_run_id"]`. **Recommended** — preserves agency compat without losing forensic data. This is the only **RENAME** in the whole delta. Everything else is additive. --------------------------------------------------------------------------- ## C. Per-primitive specifics (only fields that differ from §A) --------------------------------------------------------------------------- ### C.1 RoleComponent (types.rs:183-203) | Field | wg has? | agency has? | verdict | |-----------------|---------|-------------|---------| | category | YES `ComponentCategory ∈ {translated, enhanced, novel}` (rs:35-44, 188) | NO | KEEP — wg superset, currently load-bearing for hash (hash.rs:25). Will become a *non-hashed* field after research-agency-hash-compat lands — defer the decision there | | content | YES `ContentRef ∈ {Name|File|Url|Inline}` (rs:14-21, 189) | NO (description is the content) | KEEP — wg superset, currently load-bearing for hash (hash.rs:25). Same disposition as `category`: superset for now, defer hash semantics to research-agency-hash-compat | | requires_human_oversight | NO (only on DesiredOutcome) | NO | n/a — neither has it on RoleComponent | ### C.2 DesiredOutcome (types.rs:208-230) | Field | wg has? | agency has? | verdict | |---------------------------|---------|-------------|---------| | success_criteria | YES `Vec<String>` (rs:214) | NO (subsumed in description) | KEEP — wg superset, currently load-bearing for hash (hash.rs:42). Same disposition as `category`/`content` above; defer to research-agency-hash-compat | | requires_human_oversight | YES `bool` default `true` (rs:220-221) | NO | KEEP — wg superset; powers wg's oversight cascade (no agency conflict) | ### C.3 TradeoffConfig (types.rs:239-261) | Field | wg has? | agency has? | verdict | |-------------------------|---------|-------------|---------| | acceptable_tradeoffs | YES `Vec<String>` (rs:245) | NO (subsumed in description) | KEEP — wg superset, currently load-bearing for hash (hash.rs:67). Defer to research-agency-hash-compat | | unacceptable_tradeoffs | YES `Vec<String>` (rs:247) | NO (subsumed in description) | KEEP — wg superset, currently load-bearing for hash (hash.rs:68). Defer to research-agency-hash-compat | --------------------------------------------------------------------------- ## D. Aggregate fix proposal --------------------------------------------------------------------------- ### D.1 ADD as serde-optional fields (additive, federation-relevant) On all three primitives — applied identically to RoleComponent, DesiredOutcome, and TradeoffConfig: ```rust #[serde(default, skip_serializing_if = "Option::is_none")] pub quality: Option<u8>, // 0..=100; agency primitive store filter #[serde(default, skip_serializing_if = "Option::is_none")] pub domain_specificity: Option<u8>, // 0..=100 #[serde(default, skip_serializing_if = "Option::is_none")] pub domain: Option<Domain>, // enum: Software | Research | Writing | Analysis | Legal | Strategy | Science | Management #[serde(default, skip_serializing_if = "Option::is_none")] pub scope: Option<Scope>, // enum: Task | MetaAssigner | MetaEvaluator | MetaEvolver | MetaAgentCreator #[serde(default, skip_serializing_if = "Option::is_none")] pub origin_instance_id: Option<String>, #[serde(default, skip_serializing_if = "Option::is_none")] pub parent_content_hash: Option<String>, // legacy single-parent ref; mirror of lineage.parent_ids[0] for CSV roundtrip ``` On `Lineage` (types.rs:124-149): ```rust #[serde(default, skip_serializing_if = "Option::is_none")] pub reframing_potential: Option<f64>, // v1.2.4 lineage addition ``` ### D.2 RENAME for compat (single, surgical) `Lineage::created_by`: keep field name and string type, but constrain emitted values to agency's enum domain `{human, import, evolver, agent_creator}`. Migrate existing `"evolver-{run_id}"` → `"evolver"`, park `run_id` in primitive `metadata["evolver_run_id"]` to preserve forensic chain. This is a *value migration*, not a struct rename. Code points to update: - Lineage::mutation (types.rs:153-160): emit `"evolver"`, push run_id to metadata - Lineage::crossover (types.rs:163-173): same - default_created_by (types.rs:136-138): already correct (`"human"`) - Anywhere else evolver_run_id is consumed for provenance ### D.3 KEEP as documented superset (wg-only, non-conflicting) These wg fields have NO agency analog and NO conflict — keep them and document them in the spec-delta doc as wg extensions: - `RoleComponent::category` (ComponentCategory enum) - `RoleComponent::content` (ContentRef enum) - `DesiredOutcome::success_criteria` - `DesiredOutcome::requires_human_oversight` - `TradeoffConfig::acceptable_tradeoffs` - `TradeoffConfig::unacceptable_tradeoffs` - `*::access_control` (AccessControl) - `*::performance` (PerformanceRecord) — agency uses a separate primitive_performance table; wg keeps it inline. No conflict; CSV import/export simply ignores the field (CSV has no perf data anyway) - `*::domain_tags` - `*::metadata` - `*::former_agents` - `*::former_deployments` - `Lineage::created_at` (agency uses table-level timestamps; wg keeps inline) ### D.4 ADD-LATER (agency-internal columns, not federation-critical) - `permission_block` (13-char permission string, spec.md:705) - `override_capability` (boolean, spec.md:705) These exist in the agency SQLite schema but are absent from the v1.2.4 starter CSV. They are NOT needed for federation hash compat and NOT needed for byte-equality roundtrip of starter.csv. Defer to impl-agency-integration as additive Option<...> fields if/when wg starts authoring permission policy on primitives. --------------------------------------------------------------------------- ## E. Hash-input implications (defer to research-agency-hash-compat) --------------------------------------------------------------------------- Three of the §A "ADD" fields and seven of the §C "KEEP" fields touch the hash boundary: **Currently in wg hash, NOT in agency hash** (these are the load-bearing delta — same primitive will get a different content_hash on each side): - `RoleComponent`: `category`, `content` (hash.rs:16-35) vs agency hashes `description` only - `DesiredOutcome`: `success_criteria` (hash.rs:39-52) vs agency hashes `description` only - `TradeoffConfig`: `acceptable_tradeoffs`, `unacceptable_tradeoffs` (hash.rs:56-75) vs agency hashes `description` only **NOT currently hashed by either side** (safe to add): - `quality`, `domain_specificity`, `domain`, `scope`, `origin_instance_id`, `parent_content_hash`, `reframing_potential` — ALL purely metadata. Adding them to wg as serde-optional will NOT change wg content hashes (because hash.rs is fixed-input — see hash.rs:21-32, 41-49, 61-71 — the hash struct is independent of the primitive struct). **Consequence for this task:** all D.1 ADDs and the D.2 created_by constraint are hash-stable. The hard hash question (whether to drop `category`/`content`/`success_criteria`/`*_tradeoffs` from the wg hash input to match agency) is the load-bearing question — owned by research-agency-hash-compat. --------------------------------------------------------------------------- ## F. Federation hash-compat vs metadata-only — per-field --------------------------------------------------------------------------- | Field | Hash-compat critical? | Reason | |---------------------------|-----------------------|--------| | description | YES (BOTH SIDES) | Sole hash input on agency side; one of several on wg | | category | YES (wg only) | wg-side hash input; agency doesn't know; load-bearing for content_hash divergence | | content | YES (wg only) | wg-side hash input; same as above | | success_criteria | YES (wg only) | wg-side hash input on DesiredOutcome | | acceptable_tradeoffs | YES (wg only) | wg-side hash input on TradeoffConfig | | unacceptable_tradeoffs | YES (wg only) | wg-side hash input on TradeoffConfig | | quality | NO | Pure metadata, not hashed by either side | | domain_specificity | NO | Pure metadata | | domain | NO | Pure metadata | | scope | NO | Pure metadata; functional-agent gating happens at composition time, not hash time | | origin_instance_id | NO | Pure metadata; provenance only | | parent_content_hash | NO | Pure metadata; lineage view only | | Lineage::* | NO | Lineage is observed history, not identity | | reframing_potential | NO | Pure metadata | | access_control | NO | wg superset; not hashed | | performance | NO | wg superset; not hashed (would defeat content-hash semantics if it were) | | domain_tags | NO | wg superset; not hashed | | metadata | NO | wg superset; not hashed | | former_agents | NO | wg superset; not hashed | | former_deployments | NO | wg superset; not hashed | | permission_block | NO | Agency stores but doesn't hash | | override_capability | NO | Agency stores but doesn't hash | **One-line summary:** every field this task proposes to ADD is metadata (safe). Every field marked KEEP-as-superset that's currently in wg's hash input is the load-bearing federation-hash question — and is explicitly owned by research-agency-hash-compat. This task does NOT touch hash inputs. --------------------------------------------------------------------------- ## G. Citations summary --------------------------------------------------------------------------- WG primitive structs (file:line): - ContentRef: src/agency/types.rs:14-21 - ComponentCategory: src/agency/types.rs:35-44 - AccessControl: src/agency/types.rs:56-69 - DeploymentRef: src/agency/types.rs:72-78 - StalenessFlag: src/agency/types.rs:89-96 - PerformanceRecord: src/agency/types.rs:115-121 - Lineage: src/agency/types.rs:124-149 - RoleComponent: src/agency/types.rs:183-203 - DesiredOutcome: src/agency/types.rs:208-230 - TradeoffConfig: src/agency/types.rs:239-261 WG hash inputs (file:line): - content_hash_component: src/agency/hash.rs:14-35 - content_hash_outcome: src/agency/hash.rs:37-52 - content_hash_tradeoff: src/agency/hash.rs:54-75 Agency specification.md sections (v1.2.3 file at /home/erik/agency/specification.md): - Primitives + quality threshold: lines 33-43 - Metaprimitives + scope enum: lines 45-49 - Composition config: lines 51-53 - Starter CSV columns (v1.2.3): line 449 - v1.2.0 primitives table columns: line 705 ("primitives table gains new columns: quality, domain_specificity, domain, origin_instance_id, parent_content_hash, permission_block, override_capability") - v1.2.3 scope migration: line 727 Agency v1.2.4 lineage additions (parent_ids, generation, created_by, reframing_potential): per design-agency-sync §A.1 in this task's context — local clone is at v1.2.3, so these citations are by reference to the predecessor research task, not to a local file. --------------------------------------------------------------------------- ## H. Recommendation summary --------------------------------------------------------------------------- 7 fields to ADD on each of the 3 primitive types (21 field-additions total, all serde-optional, all metadata-only): quality, domain_specificity, domain, scope, origin_instance_id, parent_content_hash, plus reframing_potential on Lineage. 1 RENAME (value migration): Lineage::created_by — constrain to enum domain, park run_id in metadata. 13 KEEP-as-superset (no change): ContentRef, ComponentCategory, success_criteria, accept/unaccept tradeoffs, requires_human_oversight, AccessControl, PerformanceRecord, domain_tags, metadata, former_agents, former_deployments, Lineage::created_at, plus 5 of these that are currently load-bearing for the wg hash — defer hash decision to research-agency-hash-compat. 2 fields ADD-LATER: permission_block, override_capability — agency-internal, not in starter CSV, not federation-critical. Net behavior change: byte-for-byte starter.csv ingest succeeds (with quality > 90 filter respected), and content hashes do NOT change for existing wg primitives (because new ADD fields are not hashed).
- 2026-05-04T18:42:50.490785772+00:00 Validated: per-type diff tables written for RoleComponent/DesiredOutcome/TradeoffConfig + Lineage; ADD/RENAME/KEEP recommendation per field; src/agency/types.rs file:line cited per wg field; specification.md cited per agency field; hash-compat vs metadata-only flagged per field (defer hash decision to research-agency-hash-compat).
- 2026-05-04T18:43:25.523947250+00:00 Task pending eval (agent reported done; awaiting `.evaluate-*` to score)
- 2026-05-04T18:44:55.195534868+00:00 PendingEval → Done (evaluator passed; downstream unblocks)