From 03dc1f7934adc501c87c525643234df25474085e Mon Sep 17 00:00:00 2001 From: Yvette Carlisle Date: Tue, 2 Jun 2026 17:41:26 +0800 Subject: [PATCH] {"schema":"decodex/commit/1","summary":"Finish radar automation wiring","authority":"manual"} --- .github/workflows/refresh-release-delta.yml | 5 +- .github/workflows/refresh-upstream-radar.yml | 3 +- apps/decodex/src/cli.rs | 8 +- apps/decodex/src/radar.rs | 78 ++++- artifacts/github/README.md | 3 +- .../github/bundles/openai-codex-pr-25636.json | 116 +++++++ .../github/impact/openai-codex-pr-25636.json | 44 +++ .../review-queue/openai-codex-latest.json | 305 ++++++++++-------- .../reviews/openai-codex-pr-25636.review.json | 65 ++++ .../2026-06-02/openai-codex-pr-25636.json | 60 ++++ dev/skills/rate-limit-reset-watch/SKILL.md | 6 +- dev/skills/x-post-publisher/SKILL.md | 5 + docs/runbook/local-github-signal-workflow.md | 11 +- docs/runbook/social-publishing-workflow.md | 4 + docs/spec/reset-status.md | 10 +- docs/spec/social-publishing.md | 5 + site/src/content/reset-status/latest.json | 28 +- 17 files changed, 570 insertions(+), 186 deletions(-) create mode 100644 artifacts/github/bundles/openai-codex-pr-25636.json create mode 100644 artifacts/github/impact/openai-codex-pr-25636.json create mode 100644 artifacts/github/reviews/openai-codex-pr-25636.review.json create mode 100644 artifacts/social/x/posts/2026-06-02/openai-codex-pr-25636.json diff --git a/.github/workflows/refresh-release-delta.yml b/.github/workflows/refresh-release-delta.yml index 42b6e6f8..937cd836 100644 --- a/.github/workflows/refresh-release-delta.yml +++ b/.github/workflows/refresh-release-delta.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 30 env: - GH_API_TOKEN: ${{ secrets.GITHUB_PAT_Y }} + GITHUB_TOKEN: ${{ github.token }} steps: - name: Fetch latest code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -42,8 +42,7 @@ jobs: cargo run -p decodex --bin decodex -- radar refresh-release-delta \ --repo openai/codex \ --signals-dir site/src/content/signals \ - --out site/src/content/release-deltas/openai-codex-latest.json \ - --token-env GH_API_TOKEN + --out site/src/content/release-deltas/openai-codex-latest.json - name: Detect content changes id: changes diff --git a/.github/workflows/refresh-upstream-radar.yml b/.github/workflows/refresh-upstream-radar.yml index b1474988..c4396fd7 100644 --- a/.github/workflows/refresh-upstream-radar.yml +++ b/.github/workflows/refresh-upstream-radar.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 30 env: - GH_API_TOKEN: ${{ secrets.GITHUB_PAT_Y }} + GITHUB_TOKEN: ${{ github.token }} steps: - name: Fetch latest code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -41,7 +41,6 @@ jobs: run: | cargo run -p decodex --bin decodex -- radar refresh-upstream-queue \ --repo openai/codex \ - --token-env GH_API_TOKEN \ --search-limit 40 - name: Detect content changes diff --git a/apps/decodex/src/cli.rs b/apps/decodex/src/cli.rs index 4ae46f0c..ecdf08bb 100644 --- a/apps/decodex/src/cli.rs +++ b/apps/decodex/src/cli.rs @@ -1712,7 +1712,7 @@ mod tests { "--repo", "openai/codex", "--token-env", - "GH_API_TOKEN", + "GITHUB_TOKEN", "--search-limit", "40", ]); @@ -1730,7 +1730,7 @@ mod tests { } ), }) if repo == "openai/codex" - && token_env == "GH_API_TOKEN" + && token_env == "GITHUB_TOKEN" && queue_out == Path::new("artifacts/github/review-queue/openai-codex-latest.json") )); } @@ -1748,7 +1748,7 @@ mod tests { "--out", "site/src/content/release-deltas/openai-codex-latest.json", "--token-env", - "GH_API_TOKEN", + "GITHUB_TOKEN", ]); assert!(matches!( @@ -1765,7 +1765,7 @@ mod tests { } ), }) if repo == "openai/codex" - && token_env == "GH_API_TOKEN" + && token_env == "GITHUB_TOKEN" && signals_dir == Path::new("site/src/content/signals") && out == Path::new("site/src/content/release-deltas/openai-codex-latest.json") )); diff --git a/apps/decodex/src/radar.rs b/apps/decodex/src/radar.rs index 33d06df3..e3844942 100644 --- a/apps/decodex/src/radar.rs +++ b/apps/decodex/src/radar.rs @@ -1115,12 +1115,7 @@ pub(crate) fn ledger_summary( /// Build a deterministic GitHub change bundle and write it to disk. pub(crate) fn build_bundle(request: &RadarBundleBuildRequest) -> crate::prelude::Result { - let token_env = request - .token_env - .clone() - .or_else(routed_token_env) - .unwrap_or_else(|| "GITHUB_TOKEN".into()); - let token = env::var(&token_env).ok().filter(|value| !value.is_empty()); + let token = github_token(request.token_env.as_deref()); let client = GithubClient::new(token.as_deref())?; let bundle = match (request.pr, request.commit.as_deref()) { (Some(pr_number), _) => client.build_pr_bundle(&request.repo, pr_number, &request.notes)?, @@ -2227,11 +2222,16 @@ fn repo_default_branch(api: &GitHubApi, repo: &str) -> crate::prelude::Result) -> Option { - let token_env = token_env - .map(str::to_owned) - .or_else(routed_token_env) - .unwrap_or_else(|| "GITHUB_TOKEN".to_owned()); + if let Some(token_env) = token_env { + return env_token(token_env); + } + + routed_token_env() + .and_then(|token_env| env_token(&token_env)) + .or_else(|| env_token("GITHUB_TOKEN")) +} +fn env_token(token_env: &str) -> Option { env::var(token_env).ok().filter(|token| !token.is_empty()) } @@ -5511,6 +5511,8 @@ fn known_schemas() -> String { #[cfg(test)] mod tests { use std::{ + env, + ffi::OsString, fs, path::{Path, PathBuf}, }; @@ -5524,6 +5526,41 @@ mod tests { RefreshKind, }; + struct TestEnvVars { + _lock: crate::test_support::TestEnvLockGuard, + previous: Vec<(String, Option)>, + } + + impl TestEnvVars { + fn set(vars: &[(&str, Option<&str>)]) -> Self { + let lock = crate::test_support::TestEnvVarGuard::lock(); + let previous = vars + .iter() + .map(|(key, _)| ((*key).to_owned(), env::var_os(key))) + .collect::>(); + + for (key, value) in vars { + match value { + Some(value) => unsafe { env::set_var(key, value) }, + None => unsafe { env::remove_var(key) }, + } + } + + Self { _lock: lock, previous } + } + } + + impl Drop for TestEnvVars { + fn drop(&mut self) { + for (key, previous) in self.previous.drain(..).rev() { + match previous { + Some(previous) => unsafe { env::set_var(key, previous) }, + None => unsafe { env::remove_var(key) }, + } + } + } + } + #[test] fn accepts_valid_bundle_and_rejects_missing_commits() { let mut bundle = valid_bundle(); @@ -5728,6 +5765,27 @@ mod tests { assert_errors(&social_post, ["decision.daily_limit must be 8"]); } + #[test] + fn default_github_token_falls_back_to_workflow_token() { + let _env = TestEnvVars::set(&[ + ("GITHUB_PAT_X", Some("")), + ("GITHUB_PAT_Y", Some("")), + ("GITHUB_TOKEN", Some("workflow-token")), + ]); + + assert_eq!(super::github_token(None).as_deref(), Some("workflow-token")); + } + + #[test] + fn explicit_github_token_env_does_not_fall_back_to_workflow_token() { + let _env = TestEnvVars::set(&[ + ("DECODEX_TEST_MISSING_RADAR_TOKEN", None), + ("GITHUB_TOKEN", Some("workflow-token")), + ]); + + assert_eq!(super::github_token(Some("DECODEX_TEST_MISSING_RADAR_TOKEN")), None); + } + #[test] fn validates_json_files_from_directory() { let temp_dir = tempfile::tempdir().expect("temporary directory should be created"); diff --git a/artifacts/github/README.md b/artifacts/github/README.md index 6f1695a6..785043a7 100644 --- a/artifacts/github/README.md +++ b/artifacts/github/README.md @@ -11,5 +11,6 @@ at most 21 days, then move cold batches to dedicated `radar-archive-*` GitHub Re assets and keep the recovery manifest under `artifacts/archive/index/`. Rust-owned bundle build and validation commands live under `decodex radar bundle ...`. -Remaining deterministic scripts live under `scripts/github/` during migration. +The remaining `scripts/github/` files are AI-helper and schema-support surfaces, not +GitHub Actions deterministic refresh entrypoints. Repo-local editorial instructions live under `dev/skills/github-signal/`. diff --git a/artifacts/github/bundles/openai-codex-pr-25636.json b/artifacts/github/bundles/openai-codex-pr-25636.json new file mode 100644 index 00000000..afa7bd97 --- /dev/null +++ b/artifacts/github/bundles/openai-codex-pr-25636.json @@ -0,0 +1,116 @@ +{ + "analysis_mode": "pr_first", + "commits": [ + { + "author": "jif-oai", + "committed_at": "2026-06-01T15:55:10Z", + "message": "Rename multi-agent v2 assign_task tool", + "sha": "c9bdb5255b2b4b5d365a1be3ec3a94e34a4e0af0", + "url": "https://github.com/openai/codex/commit/c9bdb5255b2b4b5d365a1be3ec3a94e34a4e0af0" + } + ], + "default_branch": "main", + "docs_refs": [ + "codex-rs/rollout-trace/README.md" + ], + "examples_refs": [], + "extracted_flags": [ + "DEFAULT_MULTI_AGENT_V2_SUBAGENT_USAGE_HINT_TEXT", + "MAX_WAIT_TIMEOUT_MS", + "MIN_WAIT_TIMEOUT_MS" + ], + "files": [ + { + "additions": 2, + "deletions": 2, + "patch_excerpt": "@@ -195,7 +195,7 @@ At the start of your turn, you are the active agent.\n You can spawn sub-agents to handle subtasks, and those sub-agents can spawn their own sub-agents.\n All agents in the team, including the agents that you can assign tasks to, are equally intelligent and capable, and have access to the same set of tools.\n \n-You can use `spawn_agent` to create a new agent, `assign_task` to give an existing agent a new task and trigger a turn, and `send_message` to pass a message to a running agent without triggering a turn.\n+You can use `spawn_agent` to create a new agent, `followup_task` to give an existing agent a new task and trigger a turn, and `send_message` to pass a message to a running agent without triggering a turn.\n Child agents can also spawn their own sub-agents.\n You can decide how much context you want to propagate to your sub-agents with the `fork_turns` parameter.\n \n@...", + "path": "codex-rs/core/src/config/mod.rs", + "status": "modified" + }, + { + "additions": 5, + "deletions": 4, + "patch_excerpt": "@@ -179,12 +179,13 @@ pub fn create_send_message_tool() -> ToolSpec {\n })\n }\n \n-pub fn create_assign_task_tool() -> ToolSpec {\n+pub fn create_followup_task_tool() -> ToolSpec {\n let properties = BTreeMap::from([\n (\n \"target\".to_string(),\n JsonSchema::string(Some(\n- \"Agent id or canonical task name to message (from spawn_agent).\".to_string(),\n+ \"Agent id or canonical task name to send a follow-up task to (from spawn_agent).\"\n+ .to_string(),\n )),\n ),\n (\n@@ -196,8 +197,8 @@ pub fn create_assign_task_tool() -> ToolSpec {\n ]);\n \n ToolSpec::Function(ResponsesApiTool {\n- name: \"assign_task\".to_string(),\n- description: \"Send a message to an existing non-root target agent and trigger a turn in that target. If the target is currently mid-turn, the message is qu...", + "path": "codex-rs/core/src/tools/handlers/multi_agents_spec.rs", + "status": "modified" + }, + { + "additions": 5, + "deletions": 5, + "patch_excerpt": "@@ -247,25 +247,25 @@ fn send_message_tool_requires_message_and_has_no_output_schema() {\n }\n \n #[test]\n-fn assign_task_tool_requires_message_and_has_no_output_schema() {\n+fn followup_task_tool_requires_message_and_has_no_output_schema() {\n let ToolSpec::Function(ResponsesApiTool {\n name,\n parameters,\n output_schema,\n ..\n- }) = create_assign_task_tool()\n+ }) = create_followup_task_tool()\n else {\n- panic!(\"assign_task should be a function tool\");\n+ panic!(\"followup_task should be a function tool\");\n };\n- assert_eq!(name, \"assign_task\");\n+ assert_eq!(name, \"followup_task\");\n assert_eq!(\n parameters.schema_type,\n Some(JsonSchemaType::Single(JsonSchemaPrimitiveType::Object))\n );\n let properties = parameters\n .properties\n .as_ref()\n- .expect(\"assign_task should use object pa...", + "path": "codex-rs/core/src/tools/handlers/multi_agents_spec_tests.rs", + "status": "modified" + }, + { + "additions": 15, + "deletions": 13, + "patch_excerpt": "@@ -8,8 +8,8 @@ use crate::session::tests::make_session_and_context;\n use crate::session_prefix::format_subagent_notification_message;\n use crate::thread_manager::thread_store_from_config;\n use crate::tools::context::ToolOutput;\n-use crate::tools::handlers::multi_agents_v2::AssignTaskHandler as AssignTaskHandlerV2;\n use crate::tools::handlers::multi_agents_v2::CloseAgentHandler as CloseAgentHandlerV2;\n+use crate::tools::handlers::multi_agents_v2::FollowupTaskHandler as FollowupTaskHandlerV2;\n use crate::tools::handlers::multi_agents_v2::ListAgentsHandler as ListAgentsHandlerV2;\n use crate::tools::handlers::multi_agents_v2::SendMessageHandler as SendMessageHandlerV2;\n use crate::tools::handlers::multi_agents_v2::SpawnAgentHandler as SpawnAgentHandlerV2;\n@@ -1413,7 +1413,7 @@ async fn multi_agent_v2_send_message_accepts_root_target_from_child() {\n }\n \n #[tokio::test]\n-async fn multi_agent_...", + "path": "codex-rs/core/src/tools/handlers/multi_agents_tests.rs", + "status": "modified" + }, + { + "additions": 2, + "deletions": 2, + "patch_excerpt": "@@ -28,15 +28,15 @@ use serde::Deserialize;\n use serde::Serialize;\n use serde_json::Value as JsonValue;\n \n-pub(crate) use assign_task::Handler as AssignTaskHandler;\n pub(crate) use close_agent::Handler as CloseAgentHandler;\n+pub(crate) use followup_task::Handler as FollowupTaskHandler;\n pub(crate) use list_agents::Handler as ListAgentsHandler;\n pub(crate) use send_message::Handler as SendMessageHandler;\n pub(crate) use spawn::Handler as SpawnAgentHandler;\n pub(crate) use wait::Handler as WaitAgentHandler;\n \n-mod assign_task;\n mod close_agent;\n+mod followup_task;\n mod list_agents;\n mod message_tool;\n mod send_message;", + "path": "codex-rs/core/src/tools/handlers/multi_agents_v2.rs", + "status": "modified" + }, + { + "additions": 5, + "deletions": 5, + "patch_excerpt": "@@ -1,28 +1,28 @@\n-use super::message_tool::AssignTaskArgs;\n+use super::message_tool::FollowupTaskArgs;\n use super::message_tool::MessageDeliveryMode;\n use super::message_tool::handle_message_string_tool;\n use super::*;\n-use crate::tools::handlers::multi_agents_spec::create_assign_task_tool;\n+use crate::tools::handlers::multi_agents_spec::create_followup_task_tool;\n use codex_tools::ToolSpec;\n \n pub(crate) struct Handler;\n \n #[async_trait::async_trait]\n impl ToolExecutor for Handler {\n fn tool_name(&self) -> ToolName {\n- ToolName::plain(\"assign_task\")\n+ ToolName::plain(\"followup_task\")\n }\n \n fn spec(&self) -> ToolSpec {\n- create_assign_task_tool()\n+ create_followup_task_tool()\n }\n \n async fn handle(\n &self,\n invocation: ToolInvocation,\n ) -> Result, FunctionCallE...", + "path": "codex-rs/core/src/tools/handlers/multi_agents_v2/followup_task.rs", + "status": "renamed" + }, + { + "additions": 5, + "deletions": 5, + "patch_excerpt": "@@ -1,6 +1,6 @@\n //! Shared argument parsing and dispatch for the v2 text-only agent messaging tools.\n //!\n-//! `send_message` and `assign_task` share the same submission path and differ only in whether the\n+//! `send_message` and `followup_task` share the same submission path and differ only in whether the\n //! resulting `InterAgentCommunication` should wake the target immediately.\n \n use super::*;\n@@ -40,8 +40,8 @@ pub(crate) struct SendMessageArgs {\n \n #[derive(Debug, Deserialize)]\n #[serde(deny_unknown_fields)]\n-/// Input for the MultiAgentV2 `assign_task` tool.\n-pub(crate) struct AssignTaskArgs {\n+/// Input for the MultiAgentV2 `followup_task` tool.\n+pub(crate) struct FollowupTaskArgs {\n pub(crate) target: String,\n pub(crate) message: String,\n }\n@@ -55,7 +55,7 @@ fn message_content(message: String) -> Result {\n Ok(message)\n }\n \n-/// Handles the...", + "path": "codex-rs/core/src/tools/handlers/multi_agents_v2/message_tool.rs", + "status": "modified" + }, + { + "additions": 2, + "deletions": 2, + "patch_excerpt": "@@ -38,8 +38,8 @@ use crate::tools::handlers::multi_agents_common::MAX_WAIT_TIMEOUT_MS;\n use crate::tools::handlers::multi_agents_common::MIN_WAIT_TIMEOUT_MS;\n use crate::tools::handlers::multi_agents_spec::SpawnAgentToolOptions;\n use crate::tools::handlers::multi_agents_spec::WaitAgentTimeoutOptions;\n-use crate::tools::handlers::multi_agents_v2::AssignTaskHandler as AssignTaskHandlerV2;\n use crate::tools::handlers::multi_agents_v2::CloseAgentHandler as CloseAgentHandlerV2;\n+use crate::tools::handlers::multi_agents_v2::FollowupTaskHandler as FollowupTaskHandlerV2;\n use crate::tools::handlers::multi_agents_v2::ListAgentsHandler as ListAgentsHandlerV2;\n use crate::tools::handlers::multi_agents_v2::SendMessageHandler as SendMessageHandlerV2;\n use crate::tools::handlers::multi_agents_v2::SpawnAgentHandler as SpawnAgentHandlerV2;\n@@ -686,7 +686,7 @@ fn add_collaboration_tools(context: &CoreTo...", + "path": "codex-rs/core/src/tools/spec_plan.rs", + "status": "modified" + }, + { + "additions": 26, + "deletions": 4, + "patch_excerpt": "@@ -766,6 +766,7 @@ async fn multi_agent_feature_selects_one_agent_tool_family() {\n \"wait_agent\",\n \"close_agent\",\n \"send_message\",\n+ \"followup_task\",\n \"assign_task\",\n \"list_agents\",\n ]);\n@@ -790,12 +791,12 @@ async fn multi_agent_feature_selects_one_agent_tool_family() {\n v2.assert_visible_contains(&[\n \"spawn_agent\",\n \"send_message\",\n- \"assign_task\",\n+ \"followup_task\",\n \"wait_agent\",\n \"close_agent\",\n \"list_agents\",\n ]);\n- v2.assert_visible_lacks(&[\"send_input\", \"resume_agent\"]);\n+ v2.assert_visible_lacks(&[\"send_input\", \"resume_agent\", \"assign_task\"]);\n let spawn_agent_description = match v2.visible_spec(\"spawn_agent\") {\n ToolSpec::Function(tool) => tool.description.as_str(),\n other => panic!(\"expected spawn_agent function spec, got {other:?}\"),\n@@ -8...", + "path": "codex-rs/core/src/tools/spec_plan_tests.rs", + "status": "modified" + }, + { + "additions": 1, + "deletions": 1, + "patch_excerpt": "@@ -177,7 +177,7 @@ the edges between them.\n \n ```mermaid\n flowchart LR\n- RootTool[\"root ToolCall\\nspawn_agent / assign_task / send_message\"]\n+ RootTool[\"root ToolCall\\nspawn_agent / followup_task / send_message\"]\n ChildInput[\"child ConversationItem\\ninjected task/message\"]\n ChildThread[\"child AgentThread\"]\n ChildResult[\"child assistant ConversationItem\\nresult message\"]", + "path": "codex-rs/rollout-trace/README.md", + "status": "modified" + }, + { + "additions": 1, + "deletions": 1, + "patch_excerpt": "@@ -267,7 +267,7 @@ fn dispatched_tool_kind(tool_name: &str, _payload: &ToolDispatchPayload) -> Tool\n \"image_generation\" | \"image_query\" => ToolCallKind::ImageGeneration,\n \"spawn_agent\" => ToolCallKind::SpawnAgent,\n \"send_message\" => ToolCallKind::SendMessage,\n- \"assign_task\" | \"followup_task\" => ToolCallKind::AssignAgentTask,\n+ \"followup_task\" | \"assign_task\" => ToolCallKind::AssignAgentTask,\n \"wait_agent\" => ToolCallKind::WaitAgent,\n \"close_agent\" => ToolCallKind::CloseAgent,\n other => ToolCallKind::Other {", + "path": "codex-rs/rollout-trace/src/tool_dispatch.rs", + "status": "modified" + } + ], + "linked_issues": [], + "notes": [ + "Built from GitHub pull-request, commits, files, and repo endpoints." + ], + "primary_pr": { + "body": "## Summary\n\nRenames the MultiAgentV2 turn-triggering tool from `assign_task` to `followup_task` so the exposed tool name better describes sending an additional task to an existing agent.\n\nThis updates the tool spec, handler/module names, registry wiring, default multi-agent v2 usage hints, and tests. Rollout trace classification keeps accepting legacy `assign_task` events so older traces still reduce correctly, while docs show the new tool name.\n\n## Test plan\n\n- `just test -p codex-core followup_task`\n- `just test -p codex-core -E 'test(multi_agent_feature_selects_one_agent_tool_family) | test(multi_agent_v2_can_use_configured_tool_namespace) | test(code_mode_only_can_expose_namespaced_multi_agent_v2_as_normal_tools)'`\n- `just test -p codex-rollout-trace`\n- `just fix -p codex-core`\n- `just fix -p codex-rollout-trace`\n\nNotes: `just fmt` ran `cargo fmt` but failed in the Python ruff phase because the local environment could not resolve `hatchling>=1.27.0` from the configured internal registry. A full `just test -p codex-core` also hit unrelated environment-sensitive integration failures involving missing spawned test binaries/sandbox behavior; the changed multi-agent spec/handler tests passed in the filtered runs above.", + "labels": [], + "merged_at": "2026-06-01T17:57:12Z", + "number": 25636, + "state": "merged", + "title": "[codex] Rename multi-agent v2 assign_task to followup_task", + "url": "https://github.com/openai/codex/pull/25636" + }, + "repo": "openai/codex", + "schema": "github_change_bundle/v1" +} diff --git a/artifacts/github/impact/openai-codex-pr-25636.json b/artifacts/github/impact/openai-codex-pr-25636.json new file mode 100644 index 00000000..95bf8e7d --- /dev/null +++ b/artifacts/github/impact/openai-codex-pr-25636.json @@ -0,0 +1,44 @@ +{ + "schema": "upstream_impact/v1", + "slug": "openai-codex-pr-25636", + "repo": "openai/codex", + "source_refs": { + "items": [ + { + "kind": "pull_request", + "title": "[codex] Rename multi-agent v2 assign_task to followup_task", + "url": "https://github.com/openai/codex/pull/25636", + "meta": "Merged 2026-06-01T17:57:12Z" + }, + { + "kind": "commit", + "title": "Rename multi-agent v2 assign_task tool", + "url": "https://github.com/openai/codex/commit/c9bdb5255b2b4b5d365a1be3ec3a94e34a4e0af0" + } + ] + }, + "observed_change": "MultiAgentV2 renamed the turn-triggering agent tool from assign_task to followup_task while keeping legacy assign_task rollout-trace classification.", + "public_signal_decision": "publish", + "control_plane_impact": "compat_risk", + "publisher_angle": "operator_impact", + "confidence": "confirmed", + "evidence": [ + "PR #25636 states the exposed MultiAgentV2 tool name now better describes sending an additional task to an existing agent.", + "The tool spec now exposes followup_task and the v2 spec-plan tests assert assign_task is absent.", + "Rollout trace dispatch still accepts assign_task alongside followup_task, so historical trace reduction remains compatible.", + "Decodex currently has public MultiAgentV2 content and generated feature references, so a naming audit is actionable before newer upstream schemas are adopted." + ], + "candidate_followups": [ + "Audit Decodex docs, site content, prompts, and any future app-server tool-schema adapters for hard-coded assign_task assumptions.", + "Prefer followup_task in new MultiAgentV2 operator examples while preserving historical assign_task notes only where they describe legacy traces.", + "When Decodex consumes newer Codex app-server schemas, verify followup_task is routed as the v2 trigger-turn tool and assign_task is not required for new sessions." + ], + "social_notes": [ + "Frame as a naming and compatibility heads-up for Codex MultiAgentV2 operators, not as a Decodex runtime feature claim.", + "Mention that legacy rollout traces still classify assign_task, but newer v2 tool lists should use followup_task." + ], + "caveats": [ + "Downstream availability depends on the user's Codex build and enabled MultiAgentV2 feature state.", + "This artifact does not prove Decodex runtime support for followup_task; it identifies a compatibility audit target." + ] +} diff --git a/artifacts/github/review-queue/openai-codex-latest.json b/artifacts/github/review-queue/openai-codex-latest.json index 9afaef60..b069562b 100644 --- a/artifacts/github/review-queue/openai-codex-latest.json +++ b/artifacts/github/review-queue/openai-codex-latest.json @@ -1,14 +1,14 @@ { "counts": { "critical": 15, - "high": 6, + "high": 7, "low": 1, - "normal": 18, + "normal": 17, "published_subjects_seen": 0, "recent_commits_scanned": 40, "subjects_queued": 40 }, - "generated_at": "2026-06-02T02:36:11Z", + "generated_at": "2026-06-02T08:52:30.248308Z", "repo": "openai/codex", "schema": "upstream_review_queue/v1", "source": { @@ -17,86 +17,6 @@ "signals_dir": "site/src/content/signals" }, "subjects": [ - { - "attention_flags": [ - "breaking_change", - "new_feature", - "protocol_change" - ], - "changed_file_count": 6, - "commit_shas": [ - "cf52eb5dabb5c288ba54721f0544c6d383e18fa6" - ], - "committed_at": "2026-06-01T16:33:05Z", - "next_step": "ai_review_required", - "pr_number": 25624, - "pr_url": "https://github.com/openai/codex/pull/25624", - "review_priority": "critical", - "review_reason": "Needs AI review for breaking_change, new_feature, protocol_change.", - "sample_paths": [ - "codex-rs/rollout/src/compression_tests.rs", - "codex-rs/rollout/src/metadata.rs", - "codex-rs/rollout/src/recorder_tests.rs", - "codex-rs/rollout/src/state_db.rs", - "codex-rs/rollout/src/state_db_tests.rs", - "codex-rs/state/src/model/thread_metadata.rs" - ], - "source_state": "merged", - "subject_id": "25624", - "subject_kind": "pr", - "surface_hints": [ - "model_provider", - "tests_ci" - ], - "title": "Preserve renamed thread titles during reconciliation", - "url": "https://github.com/openai/codex/pull/25624" - }, - { - "attention_flags": [ - "auth_account", - "deprecated_removed", - "new_feature", - "protocol_change", - "security_policy" - ], - "changed_file_count": 6, - "commit_shas": [ - "e6f6a17e8a220ef5f3b7a0eaf98d6604a0af3a9f", - "7c30dd5d4bf1edac8c8a708145859f8a7c702c05", - "a7e4204463f28df53672472f71be2ba015e0476b", - "d9ca4f91c209b7a1b8177d5d183e82bbc29cc890", - "005c818463ca9b15c779df6f4fb6ef96c1441cbc", - "fa20516f6487c01f4744f3d7d75b1e8e8ef32f1f", - "acf9e8b600cc6ad8864dc2f9bd805b600fa857f2", - "4d749de426ceb5049f70dc84137bf38ddfc2f42a", - "d4ea8333e30f5ac7b62f3e04b437684a77e7fa89", - "d68c50dfc3a043fa7ae48c7ad67d366d48d983fe", - "69c3f6e1ac89e0ffb92d192edecabbf8eb78d7a8" - ], - "committed_at": "2026-06-01T16:35:58Z", - "next_step": "ai_review_required", - "pr_number": 25089, - "pr_url": "https://github.com/openai/codex/pull/25089", - "review_priority": "critical", - "review_reason": "Needs AI review for auth_account, deprecated_removed, new_feature, protocol_change, security_policy.", - "sample_paths": [ - "codex-rs/core/config.schema.json", - "codex-rs/core/src/thread_manager.rs", - "codex-rs/features/src/lib.rs", - "codex-rs/rollout/src/compression.rs", - "codex-rs/rollout/src/compression_tests.rs", - "codex-rs/rollout/src/lib.rs" - ], - "source_state": "merged", - "subject_id": "25089", - "subject_kind": "pr", - "surface_hints": [ - "config_hooks", - "tests_ci" - ], - "title": "Compress cold local rollouts", - "url": "https://github.com/openai/codex/pull/25089" - }, { "attention_flags": [ "breaking_change", @@ -684,32 +604,119 @@ }, { "attention_flags": [ + "auth_account", + "breaking_change", + "deprecated_removed", "new_feature", - "protocol_change" + "protocol_change", + "rate_limit", + "release_packaging", + "security_policy" ], - "changed_file_count": 1, + "changed_file_count": 40, "commit_shas": [ - "85ecb33ab79125fbd68c435444eda876d41e1c59", - "0ebf287187ce69a692588bd9eba2adf867031912", - "0b0ab0854c1f536912660312c0a97e4bada3270f" + "bc1f488d5461732a44051fff56efaa56edb7e877", + "f53903bb5e04adbfded417f0a0cf0293708d3c8f", + "466116d0728995e82dcc8a83c0f3a670a8c8f2bd", + "bdffb85ac200be271acc40f082a2eb98d4361368", + "9a8770e5a0295749c7b9a536515689d77fa26505", + "0c6a43a47241929e67bf345282694fc32cea68db", + "407eebdb363820c2847fc45a3f4d1f4ad97c03eb", + "fed088aa1e7bc263335bb8ab271c1e2bb9c17860", + "5629e1ac43419e725f78ecf85eadef2295196d2f", + "7e829bee95e216800b86ca95ed5e96d273b2830e", + "39091ecd6e2bb6adb7716a637d448713bce22dd2", + "1f612ac9aff3852bc993576995fb812de08d6d1a", + "144a7b432cd89629e542b0433a3d288b7b7a35fe", + "d8446b6922f749a59bc6737b03d2a155674aa918", + "8001158298e019173184ee9a95c2ab1757a9035e", + "fa8a8996ad87171fa461e80baef304b84489180f", + "eaa479ae9fff86f99bd4a990493e9b1f0e7edf87", + "157d1beceb6a6395f9f3f7490f99765901a4dada", + "8addd8104ecac6a6e0e1d8cbfe05f400ec1c2f91", + "e790a2038c6e9159ecc6454951eed4dfaf0e6a71", + "9c2d1ae16b8d4767c9c4cd6cd55ce626300fe4ab" + ], + "committed_at": "2026-06-02T04:25:42Z", + "next_step": "ai_review_required", + "pr_number": 24812, + "pr_url": "https://github.com/openai/codex/pull/24812", + "review_priority": "critical", + "review_reason": "Needs AI review for auth_account, breaking_change, deprecated_removed, new_feature, protocol_change, rate_limit, release_packaging, security_policy.", + "sample_paths": [ + "codex-rs/app-server-protocol/schema/json/ServerNotification.json", + "codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json", + "codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json", + "codex-rs/app-server-protocol/schema/json/v2/AccountRateLimitsUpdatedNotification.json", + "codex-rs/app-server-protocol/schema/json/v2/GetAccountRateLimitsResponse.json", + "codex-rs/app-server-protocol/schema/typescript/v2/AccountRateLimitsUpdatedNotification.ts", + "codex-rs/app-server-protocol/schema/typescript/v2/RateLimitSnapshot.ts", + "codex-rs/app-server-protocol/schema/typescript/v2/SpendControlLimitSnapshot.ts", + "codex-rs/app-server-protocol/schema/typescript/v2/index.ts", + "codex-rs/app-server-protocol/src/protocol/v2/account.rs", + "codex-rs/app-server/README.md", + "codex-rs/app-server/src/bespoke_event_handling.rs" ], - "committed_at": "2026-06-01T17:13:56Z", + "source_state": "merged", + "subject_id": "24812", + "subject_kind": "pr", + "surface_hints": [ + "app_server_protocol", + "auth_accounts", + "cli_tui", + "docs_examples", + "model_provider", + "tests_ci" + ], + "title": "feat: show enterprise monthly credit limits in status", + "url": "https://github.com/openai/codex/pull/24812" + }, + { + "attention_flags": [ + "auth_account", + "deprecated_removed", + "new_feature", + "protocol_change", + "release_packaging", + "security_policy" + ], + "changed_file_count": 13, + "commit_shas": [ + "ee5025e36c91294182849bbdc3e043f30d56db53", + "a1889a2dd566f8adc26892be5b32abe13b9249d2", + "2d9f1ba32017024684076b2ae6d20974df1f122f" + ], + "committed_at": "2026-06-02T05:10:52Z", "next_step": "ai_review_required", - "pr_number": 25603, - "pr_url": "https://github.com/openai/codex/pull/25603", - "review_priority": "high", - "review_reason": "Needs AI review for new_feature, protocol_change.", + "pr_number": 25457, + "pr_url": "https://github.com/openai/codex/pull/25457", + "review_priority": "critical", + "review_reason": "Needs AI review for auth_account, deprecated_removed, new_feature, protocol_change, release_packaging, security_policy.", "sample_paths": [ - "codex-rs/app-server/src/request_processors/thread_processor.rs" + "codex-rs/app-server/src/request_processors/plugins.rs", + "codex-rs/app-server/tests/suite/v2/plugin_list.rs", + "codex-rs/core-plugins/src/lib.rs", + "codex-rs/core-plugins/src/manager.rs", + "codex-rs/core-plugins/src/remote.rs", + "codex-rs/core-plugins/src/remote/catalog_cache.rs", + "codex-rs/core/src/connectors.rs", + "codex-rs/core/src/connectors_tests.rs", + "codex-rs/core/src/plugins/discoverable.rs", + "codex-rs/core/src/plugins/discoverable_tests.rs", + "codex-rs/core/src/session/turn.rs", + "codex-rs/core/src/tools/handlers/request_plugin_install.rs" ], "source_state": "merged", - "subject_id": "25603", + "subject_id": "25457", "subject_kind": "pr", "surface_hints": [ - "app_server_protocol" + "app_server_protocol", + "mcp_plugins", + "release_packaging", + "tests_ci" ], - "title": "[codex] Inherit raw events for spawned child listeners", - "url": "https://github.com/openai/codex/pull/25603" + "title": "[codex] Cache remote plugin catalog for suggestions", + "url": "https://github.com/openai/codex/pull/25457" }, { "attention_flags": [ @@ -908,73 +915,65 @@ }, { "attention_flags": [ + "auth_account", "new_feature", - "protocol_change", - "rate_limit" + "protocol_change" ], - "changed_file_count": 12, + "changed_file_count": 2, "commit_shas": [ - "46e75a8f935e8244224502764ce1bdc3435f7f10" + "64f3943195c8a34c38d95296e977dfff4c046aef" ], - "committed_at": "2026-06-01T16:30:20Z", + "committed_at": "2026-06-02T04:27:06Z", "next_step": "ai_review_required", - "pr_number": 25504, - "pr_url": "https://github.com/openai/codex/pull/25504", - "review_priority": "normal", - "review_reason": "Needs AI review for new_feature, protocol_change, rate_limit.", + "pr_number": 25330, + "pr_url": "https://github.com/openai/codex/pull/25330", + "review_priority": "high", + "review_reason": "Needs AI review for auth_account, new_feature, protocol_change.", "sample_paths": [ - "codex-rs/cli/src/doctor/title.rs", - "codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__status_line_setup__tests__setup_view_snapshot_uses_runtime_preview_values.snap", - "codex-rs/tui/src/bottom_pane/status_line_setup.rs", - "codex-rs/tui/src/bottom_pane/status_line_style.rs", - "codex-rs/tui/src/bottom_pane/status_surface_preview.rs", - "codex-rs/tui/src/bottom_pane/title_setup.rs", - "codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_line_setup_popup_hardcoded_only.snap", - "codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_line_setup_popup_live_only.snap", - "codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_line_setup_popup_mixed.snap", - "codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_line_setup_popup_rate_limits.snap", - "codex-rs/tui/src/chatwidget/status_surfaces.rs", - "codex-rs/tui/src/chatwidget/tests/status_and_layout.rs" + "codex-rs/cli/src/plugin_cmd.rs", + "codex-rs/cli/tests/plugin_cli.rs" ], "source_state": "merged", - "subject_id": "25504", + "subject_id": "25330", "subject_kind": "pr", "surface_hints": [ "cli_tui", + "mcp_plugins", "tests_ci" ], - "title": "Add reasoning-only status surface item", - "url": "https://github.com/openai/codex/pull/25504" + "title": "[codex] Add plugin list JSON output", + "url": "https://github.com/openai/codex/pull/25330" }, { "attention_flags": [ - "deprecated_removed", - "release_packaging" + "auth_account", + "new_feature", + "protocol_change", + "security_policy" ], - "changed_file_count": 2, + "changed_file_count": 3, "commit_shas": [ - "b78d153d5bc7e82dfcc2d8c185341e15d0824252", - "2bf2e7221775bb96c1f3c962faae4fb06d271e64" + "0f832b68676103eedee4e9eb4c66e6683ac3cde3" ], - "committed_at": "2026-06-01T16:49:55Z", + "committed_at": "2026-06-02T06:25:37Z", "next_step": "ai_review_required", - "pr_number": 25490, - "pr_url": "https://github.com/openai/codex/pull/25490", - "review_priority": "normal", - "review_reason": "Needs AI review for deprecated_removed, release_packaging.", + "pr_number": 25783, + "pr_url": "https://github.com/openai/codex/pull/25783", + "review_priority": "high", + "review_reason": "Needs AI review for auth_account, new_feature, protocol_change, security_policy.", "sample_paths": [ - ".github/workflows/rust-release-windows.yml", - ".github/workflows/rust-release.yml" + "codex-rs/core-plugins/src/discoverable.rs", + "codex-rs/core-plugins/src/lib.rs", + "codex-rs/core/src/plugins/discoverable.rs" ], "source_state": "merged", - "subject_id": "25490", + "subject_id": "25783", "subject_kind": "pr", "surface_hints": [ - "release_packaging", - "tests_ci" + "mcp_plugins" ], - "title": "Disable SQLite intrinsics for Windows x64 releases", - "url": "https://github.com/openai/codex/pull/25490" + "title": "[codex] Move plugin discoverable logic into core-plugins", + "url": "https://github.com/openai/codex/pull/25783" }, { "attention_flags": [ @@ -1477,6 +1476,34 @@ "title": "Move code review rules into AGENTS", "url": "https://github.com/openai/codex/pull/25738" }, + { + "attention_flags": [ + "new_feature" + ], + "changed_file_count": 2, + "commit_shas": [ + "2a107a3fe2c6a0c202a17cb77b941a610364cbb1", + "4316100ef65572ab681e49596a104c2e9dee76ca" + ], + "committed_at": "2026-06-02T06:33:02Z", + "next_step": "ai_review_required", + "pr_number": 25782, + "pr_url": "https://github.com/openai/codex/pull/25782", + "review_priority": "normal", + "review_reason": "Needs AI review for new_feature.", + "sample_paths": [ + "codex-rs/core-skills/src/loader.rs", + "codex-rs/core-skills/src/loader_tests.rs" + ], + "source_state": "merged", + "subject_id": "25782", + "subject_kind": "pr", + "surface_hints": [ + "tests_ci" + ], + "title": "[codex] Validate plugin skill base names", + "url": "https://github.com/openai/codex/pull/25782" + }, { "attention_flags": [], "changed_file_count": 1, diff --git a/artifacts/github/reviews/openai-codex-pr-25636.review.json b/artifacts/github/reviews/openai-codex-pr-25636.review.json new file mode 100644 index 00000000..d53a4e0c --- /dev/null +++ b/artifacts/github/reviews/openai-codex-pr-25636.review.json @@ -0,0 +1,65 @@ +{ + "schema": "upstream_review/v1", + "slug": "openai-codex-pr-25636", + "repo": "openai/codex", + "subject": { + "subject_kind": "pr", + "subject_id": "25636", + "commit_shas": [ + "c9bdb5255b2b4b5d365a1be3ec3a94e34a4e0af0" + ] + }, + "source_refs": { + "items": [ + { + "kind": "pull_request", + "title": "[codex] Rename multi-agent v2 assign_task to followup_task", + "url": "https://github.com/openai/codex/pull/25636", + "meta": "Merged 2026-06-01T17:57:12Z" + }, + { + "kind": "commit", + "title": "Rename multi-agent v2 assign_task tool", + "url": "https://github.com/openai/codex/commit/c9bdb5255b2b4b5d365a1be3ec3a94e34a4e0af0" + } + ] + }, + "reviewed_at": "2026-06-02T08:55:37Z", + "observed_change": "MultiAgentV2 renamed the turn-triggering agent tool from assign_task to followup_task while keeping legacy assign_task rollout-trace classification.", + "changed_surfaces": [ + "multi-agent v2 tool spec", + "tool handler registry", + "default usage hints", + "tool planning tests", + "rollout trace classification" + ], + "user_visible_path": "On Codex builds that include PR #25636 with MultiAgentV2 enabled, operators should use followup_task to send a new task to an existing non-root agent and trigger its next turn.", + "control_plane_relevance": "Decodex automation, docs, and any app-server or tool-schema integration that mirrors Codex MultiAgentV2 names must stop assuming assign_task is exposed in v2 and should prepare for followup_task.", + "compatibility_risk": "Existing Decodex-side prompts, adapters, or docs that invoke assign_task as the v2 trigger tool can drift from upstream once the new schema is active; rollout traces remain backward-compatible for old assign_task events.", + "adoption_opportunity": "Prefer followup_task in future Decodex-facing MultiAgentV2 examples while preserving legacy trace and documentation context for historical artifacts.", + "community_value": "This is a concise operator-facing rename that explains why older assign_task references may disappear from newer Codex MultiAgentV2 tool lists.", + "deprecated_or_breaking_notes": "The v2 visible tool name changes from assign_task to followup_task; upstream tests assert assign_task is absent from the v2 tool plan while rollout-trace dispatch still accepts assign_task as legacy input.", + "confidence": "confirmed", + "evidence": [ + "PR #25636 body states the MultiAgentV2 turn-triggering tool was renamed from assign_task to followup_task.", + "codex-rs/core/src/tools/handlers/multi_agents_spec.rs changes the function constructor and exposed tool name to followup_task.", + "codex-rs/core/src/tools/spec_plan_tests.rs adds followup_task to the v2 visible tool set and asserts assign_task is absent.", + "codex-rs/rollout-trace/src/tool_dispatch.rs continues to classify both followup_task and assign_task as AssignAgentTask for historical traces.", + "Normalized bundle artifacts/github/bundles/openai-codex-pr-25636.json records 11 changed files and the merged commit c9bdb5255b2b4b5d365a1be3ec3a94e34a4e0af0." + ], + "caveats": "The change is source-confirmed upstream; downstream availability still depends on which Codex build or app-server schema a user is running.", + "next_actions": [ + { + "type": "upstream_impact", + "reason": "The rename can affect Decodex Control Plane compatibility and should be tracked as an upstream impact." + }, + { + "type": "social_post", + "reason": "The rename is useful to explain publicly for operators following Codex MultiAgentV2 tooling changes." + }, + { + "type": "linear_followup", + "reason": "Decodex should audit its own prompts, docs, and adapters for assign_task assumptions before adopting newer MultiAgentV2 schemas." + } + ] +} diff --git a/artifacts/social/x/posts/2026-06-02/openai-codex-pr-25636.json b/artifacts/social/x/posts/2026-06-02/openai-codex-pr-25636.json new file mode 100644 index 00000000..c806e48b --- /dev/null +++ b/artifacts/social/x/posts/2026-06-02/openai-codex-pr-25636.json @@ -0,0 +1,60 @@ +{ + "schema": "social_post/v1", + "slug": "openai-codex-pr-25636", + "channel": "x", + "target_account": "decodexspace", + "controller_account": "hackink", + "mode": "operator_impact", + "status": "failed", + "audience": "Codex operators and Decodex Control Plane builders", + "text": [ + "Codex MultiAgentV2 renamed its trigger-turn tool: `assign_task` is now `followup_task`. PR #25636 keeps legacy rollout-trace classification for `assign_task`, so old traces still reduce correctly. Source: https://github.com/openai/codex/pull/25636" + ], + "source_refs": { + "upstream_impacts": [ + "artifacts/github/impact/openai-codex-pr-25636.json" + ], + "upstream_reviews": [ + "artifacts/github/reviews/openai-codex-pr-25636.review.json" + ], + "urls": [ + "https://github.com/openai/codex/pull/25636" + ] + }, + "evidence_notes": [ + "PR #25636 source evidence confirms the v2 exposed tool name changed from assign_task to followup_task.", + "The upstream impact artifact classifies the change as a Decodex compatibility risk with an operator_impact Publisher angle.", + "Chrome publication was not attempted after account/page verification became unreliable." + ], + "claims": [ + { + "text": "Codex MultiAgentV2 renamed the trigger-turn tool from assign_task to followup_task.", + "evidence": "https://github.com/openai/codex/pull/25636", + "confidence": "confirmed" + }, + { + "text": "Legacy rollout traces still classify assign_task as an agent-task dispatch.", + "evidence": "artifacts/github/reviews/openai-codex-pr-25636.review.json", + "confidence": "confirmed" + } + ], + "decision": { + "worthiness": "publish", + "priority": "critical", + "idempotency_key": "x:decodexspace:operator_impact:openai-codex-pr-25636", + "reason": "Source-backed MultiAgentV2 rename affects operator expectations and Decodex compatibility planning.", + "daily_limit": 8, + "daily_count_before": 0, + "daily_count_after": 0, + "day": "2026-06-02", + "timezone": "Asia/Shanghai" + }, + "failure": { + "reason": "chrome_page_verification_blocked", + "details": "Chrome opened the X search page, but page text readback reported that another extension UI was open, so @decodexspace account verification, duplicate detection, compose, media upload, and final URL readback could not be trusted." + }, + "caveats": [ + "No X post was published.", + "Retry publication only after Chrome/X account verification is reliable." + ] +} diff --git a/dev/skills/rate-limit-reset-watch/SKILL.md b/dev/skills/rate-limit-reset-watch/SKILL.md index e24ca5f8..ad99ac45 100644 --- a/dev/skills/rate-limit-reset-watch/SKILL.md +++ b/dev/skills/rate-limit-reset-watch/SKILL.md @@ -5,7 +5,7 @@ description: Use when checking whether today's @thsottiaux X posts semantically # Rate Limit Reset Watch -Use this repo-local skill to refresh the homepage `Are we reset today?` signal. +Use this repo-local skill to refresh the homepage `Rate limit reset today?` signal. The job is semantic judgment, not keyword matching. ## Inputs @@ -26,7 +26,9 @@ The job is semantic judgment, not keyword matching. 4. Decide semantically whether any candidate says rate limits reset, quota windows reset, message caps recovered, or users should wait for a reset window. 5. Write `site/src/content/reset-status/latest.json` with `schema = "reset_status/v1"`. -6. Run the site content/type validation after updating the artifact. +6. Close or release Chrome/X tabs opened for search, profile review, or thread context. + Keep a tab only when login, CAPTCHA, or another human-only X state must be handed off. +7. Run the site content/type validation after updating the artifact. ## Decision Rules diff --git a/dev/skills/x-post-publisher/SKILL.md b/dev/skills/x-post-publisher/SKILL.md index ea1cebeb..36c86750 100644 --- a/dev/skills/x-post-publisher/SKILL.md +++ b/dev/skills/x-post-publisher/SKILL.md @@ -37,6 +37,11 @@ verification, Chrome availability, X page structure, media upload, duplicate det or final URL readback is unreliable, do not post. Write `status = "failed"` or `status = "blocked"` with evidence instead. +Treat Chrome tabs as scoped resources. After account verification, compose, upload, +and final URL readback are done, close or release all tabs opened for the workflow. +Keep a tab only as an explicit human handoff, such as login, CAPTCHA, account approval, +or an unfinished operator-controlled page, and record that handoff in the result. + Style observations from X are not technical evidence. They can shape format and tone, but every technical claim must point back to GitHub, changelog, signal, upstream-review, or upstream-impact evidence. diff --git a/docs/runbook/local-github-signal-workflow.md b/docs/runbook/local-github-signal-workflow.md index db9cbcf2..30ba7356 100644 --- a/docs/runbook/local-github-signal-workflow.md +++ b/docs/runbook/local-github-signal-workflow.md @@ -118,9 +118,9 @@ decodex radar backfill-release-range \ Use release-range backfill to fill gaps in the accumulated commit/PR analysis before a release or prerelease summary. It should supplement continuous commit tracking, not replace it. Execute mode is still a Codex automation or local operator path: Rust -selects the release-window gaps and sequences deterministic Radar commands, while -`scripts/github/run_codex_analysis.py` remains the read-only Codex AI helper that -creates validated `analysis_draft` artifacts. +selects the release-window gaps and sequences deterministic Radar commands, while the +AI review step follows the repo-local skills and schemas instead of running inside +GitHub Actions. The repository already includes a real sample for this flow: @@ -198,5 +198,8 @@ The current Decodex boundary is: The GitHub Actions paths assume: -- `GITHUB_PAT_Y` is available when you want authenticated GitHub API requests for the routed `y` identity; otherwise the sync falls back to unauthenticated reads for public data +- `GITHUB_TOKEN: ${{ github.token }}` is exported by the workflow for authenticated + GitHub API requests and current-repository pushes. +- Local operator runs may use the routed `GITHUB_PAT_Y` identity or pass an explicit + `--token-env` override when they need a different credential. - `cargo make decodex-checks` remains the final gate before a content refresh commit diff --git a/docs/runbook/social-publishing-workflow.md b/docs/runbook/social-publishing-workflow.md index 9e759eee..e0e13cff 100644 --- a/docs/runbook/social-publishing-workflow.md +++ b/docs/runbook/social-publishing-workflow.md @@ -82,6 +82,8 @@ for technical claims. - Attach generated media when present. - Fail closed if account verification, duplicate detection, media upload, or final URL readback is unreliable. + - Close or release Chrome tabs before the automation ends. Keep a tab only when it + is an explicit human handoff such as login, CAPTCHA, or account approval. 7. Write the publication record. - Use `schema = "social_post/v1"`. @@ -138,6 +140,8 @@ Use `watch_note` when: - Do not publish without a source-backed worthiness decision. - Do not exceed 8 posts per cap day for `@decodexspace`. - Do not let Chrome automation keep retrying after a failed or uncertain publish. +- Do not leave research, compose, upload, search, or readback tabs open after the + publication record has captured the outcome. - Do not let social publishing bypass the static site, signal-entry, upstream-review, or upstream-impact evidence chain. - Do not quote third-party posts at length. Record style observations, not copied diff --git a/docs/spec/reset-status.md b/docs/spec/reset-status.md index f986474f..42c25f28 100644 --- a/docs/spec/reset-status.md +++ b/docs/spec/reset-status.md @@ -6,7 +6,8 @@ Status: normative Read this when: - You are changing the homepage reset-status widget. -- You are changing how Decodex decides whether "Are we reset today?" is `Yes`, `No`, or `Unknown`. +- You are changing how Decodex decides whether "Rate limit reset today?" is `Yes`, + `No`, or `Unknown`. - You are producing or reviewing the reset-status artifact. Not this document: @@ -35,7 +36,7 @@ this widget. The site reads the latest checked-in reset-status artifact under: The artifact schema is: - `schema`: must be `reset_status/v1` -- `question`: must be the rendered question, currently `Are we reset today?` +- `question`: must be the rendered question, currently `Rate limit reset today?` - `answer`: one of `yes`, `no`, or `unknown` - `confidence`: one of `confirmed`, `likely`, or `weak` - `observed_for_date`: the date being judged, formatted as `YYYY-MM-DD` @@ -70,6 +71,11 @@ The reviewer must collect today's candidate posts first, then make the semantic Good evidence can come from X profile results, X search results, quoted context, or visible thread context. +Chrome/X tabs used for search, profile review, or thread context are temporary +observation resources. Close or release them after writing the artifact. Keep a tab +open only when the run must hand off a login, CAPTCHA, or other human-only X state to +the operator. + Do not mark `yes` from generic words such as `reset`, `limit`, `fast`, `quota`, or `rate` unless the surrounding context is about rate-limit reset behavior. diff --git a/docs/spec/social-publishing.md b/docs/spec/social-publishing.md index bedd4a72..8b7b3a61 100644 --- a/docs/spec/social-publishing.md +++ b/docs/spec/social-publishing.md @@ -153,6 +153,11 @@ described here. It must use the logged-in `@decodexspace` account, verify the ac before composing, and fail closed when Chrome, login state, X page structure, duplicate detection, or media upload is unreliable. +Chrome tabs are temporary execution resources. Publisher automation must close or +release research, compose, upload, and readback tabs after the `social_post/v1` record +captures the result. A tab may stay open only as an explicit human handoff, such as +login, CAPTCHA, account approval, or a page that still requires operator input. + ## Generated Image Contract Every published X post should include a generated image unless the publication record diff --git a/site/src/content/reset-status/latest.json b/site/src/content/reset-status/latest.json index 9127db39..c7c16837 100644 --- a/site/src/content/reset-status/latest.json +++ b/site/src/content/reset-status/latest.json @@ -1,31 +1,21 @@ { "schema": "reset_status/v1", "question": "Rate limit reset today?", - "answer": "no", - "confidence": "likely", - "observed_for_date": "2026-05-13", + "answer": "unknown", + "confidence": "weak", + "observed_for_date": "2026-06-02", "timezone": "Asia/Shanghai", - "generated_at": "2026-05-13T15:27:51Z", + "generated_at": "2026-06-02T09:05:00Z", "source_account": "@thsottiaux", "source_url": "https://x.com/thsottiaux", - "search_url": "https://x.com/search?q=from%3Athsottiaux%20since%3A2026-05-13%20until%3A2026-05-14&src=typed_query&f=live", + "search_url": "https://x.com/search?q=from%3Athsottiaux%20since%3A2026-06-02%20until%3A2026-06-03&src=typed_query&f=live", "judgment_mode": "ai_semantic_review", - "rationale": "AI semantic review of today's visible @thsottiaux posts did not find a post about rate limit quota reset, cap recovery, or reset timing.", + "rationale": "Chrome reached the X search URL, but page text readback was blocked by an extension UI, so today's @thsottiaux posts could not be reviewed reliably.", "evidence_posts": [ { - "published_at_label": "9h", - "relevance": "not_related", - "summary": "Post about using ChatGPT more after GPT-5.5 Instant." - }, - { - "published_at_label": "12h", - "relevance": "not_related", - "summary": "Post about in-app browser improvements in the Codex app." - }, - { - "published_at_label": "13h", - "relevance": "not_related", - "summary": "Short reply to another X user without rate-limit reset content." + "published_at_label": "2026-06-02 search attempt", + "relevance": "uncertain", + "summary": "Opened X search for today's @thsottiaux posts, but Chrome automation could not read the page content because another extension UI was open." } ] }