Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,10 @@ account usage probes.
`decodex serve` uses hardcoded scheduler cadences: the local control-plane loop
publishes snapshots every 15 seconds, and Linear-backed queue/status scans run at
most every 5 minutes per project unless an operator or agent requests an explicit
scan with `POST /api/linear-scan`.
scan with `POST /api/linear-scan`. Persisted Execution Programs do not wait for that
ordinary queue-label scan: the runtime keeps the Program graph in local state,
refreshes only the mapped Linear issue facts needed for readiness, and directly
dispatches ready DAG nodes with `program` dispatch mode.

`decodex research compile` is the native Decodex research/design entrypoint. It
accepts minimal natural-language intake or a structured research/design JSON packet,
Expand All @@ -159,21 +162,21 @@ records explicit acceptance for a stored contract; only promoted contracts may l
feed issue shaping or internal Execution Program readiness.

`decodex intake goal` materializes a promoted Decision Contract. `--dry-run` prints
the proposed normal Linear issues, dependencies, conflict domains, and queue plan
the proposed normal Linear issues, dependencies, conflict domains, and dispatch plan
without mutating Linear or local Program Intake rows. `--apply` creates or updates the
generated normal Linear issue briefs and persists the internal Execution Program plus
contract/program links in runtime SQLite. Apply does not run implementation or apply
queue labels; later reconciliation owns queue-label changes. If the contract is still
queue labels; the persisted Program becomes eligible for direct graph dispatch on the
next scheduler pass. If the contract is still
latent, needs a decision, or lacks issue-shaping authority, intake stops before
creating executable work.

`decodex intake issues` materializes a supplied batch of existing Linear issues into
local Program Intake state. `--dry-run` prints the deterministic ready/held/blocked
report without mutation. `--apply` persists the local Program Intake Plan, Execution
Program, issue mappings, and queue-label ownership evidence when already proven, but
it still never applies or removes service queue labels directly. Program
reconciliation owns those label changes on a later scan. `--persist` remains a legacy
alias for `--apply`.
Program, and issue mappings. It never applies or removes service queue labels; ready
mapped nodes are dispatched directly by the Program scheduler instead of being
converted into queued-label work.

### Install from Source

Expand Down
33 changes: 5 additions & 28 deletions apps/decodex/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -688,8 +688,8 @@ struct IntakeIssuesCommand {
/// Read tracker state and print the deterministic intake report without local persistence.
#[arg(long, conflicts_with = "apply", required_unless_present = "apply")]
dry_run: bool,
/// Persist local runtime Program Intake records; never mutates Linear queue labels.
#[arg(long, visible_alias = "persist", conflicts_with = "dry_run")]
/// Persist local runtime Program Intake records for direct Program dispatch.
#[arg(long, conflicts_with = "dry_run")]
apply: bool,
/// Emit structured JSON instead of human-readable text.
#[arg(long)]
Expand Down Expand Up @@ -1576,6 +1576,7 @@ impl From<AttemptDispatchMode> for IssueDispatchMode {
fn from(value: AttemptDispatchMode) -> Self {
match value {
AttemptDispatchMode::Normal => Self::Normal,
AttemptDispatchMode::Program => Self::Program,
AttemptDispatchMode::Retry => Self::Retry,
AttemptDispatchMode::ReviewRepair => Self::ReviewRepair,
AttemptDispatchMode::Closeout => Self::Closeout,
Expand All @@ -1587,6 +1588,7 @@ impl From<AttemptDispatchMode> for IssueDispatchMode {
#[serde(rename_all = "kebab-case")]
pub(crate) enum AttemptDispatchMode {
Normal,
Program,
Retry,
ReviewRepair,
Closeout,
Expand All @@ -1595,6 +1597,7 @@ impl From<IssueDispatchMode> for AttemptDispatchMode {
fn from(value: IssueDispatchMode) -> Self {
match value {
IssueDispatchMode::Normal => Self::Normal,
IssueDispatchMode::Program => Self::Program,
IssueDispatchMode::Retry => Self::Retry,
IssueDispatchMode::ReviewRepair => Self::ReviewRepair,
IssueDispatchMode::Closeout => Self::Closeout,
Expand Down Expand Up @@ -2693,32 +2696,6 @@ mod tests {
));
}

#[test]
fn parses_intake_issues_legacy_persist_alias() {
let cli = Cli::parse_from([
"decodex",
"intake",
"issues",
"--project",
"decodex",
"XY-1",
"--persist",
]);

assert!(matches!(
cli.command,
Command::Intake(IntakeCommand {
command: IntakeSubcommand::Issues(IntakeIssuesCommand {
project: Some(_),
dry_run: false,
apply: true,
issues,
..
})
}) if issues == vec![String::from("XY-1")]
));
}

#[test]
fn parses_intake_goal_apply_with_project_and_team_anchor() {
let cli = Cli::parse_from([
Expand Down
Loading